fix #9040: implement service/persistent methods to get featureDtos fitting to availab...
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / term / DefinedTermDaoImpl.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.term;
11
12 import java.net.URI;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Enumeration;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Locale;
19 import java.util.Set;
20 import java.util.UUID;
21
22 import org.apache.commons.lang.StringUtils;
23 import org.apache.log4j.Logger;
24 import org.hibernate.Criteria;
25 import org.hibernate.Query;
26 import org.hibernate.Session;
27 import org.hibernate.criterion.Criterion;
28 import org.hibernate.criterion.Disjunction;
29 import org.hibernate.criterion.Order;
30 import org.hibernate.criterion.Projections;
31 import org.hibernate.criterion.Restrictions;
32 import org.hibernate.envers.query.AuditEntity;
33 import org.hibernate.envers.query.AuditQuery;
34 import org.springframework.stereotype.Repository;
35
36 import eu.etaxonomy.cdm.model.common.AnnotationType;
37 import eu.etaxonomy.cdm.model.common.CdmBase;
38 import eu.etaxonomy.cdm.model.common.ExtensionType;
39 import eu.etaxonomy.cdm.model.common.Language;
40 import eu.etaxonomy.cdm.model.common.MarkerType;
41 import eu.etaxonomy.cdm.model.description.MeasurementUnit;
42 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
43 import eu.etaxonomy.cdm.model.description.State;
44 import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
45 import eu.etaxonomy.cdm.model.description.TextFormat;
46 import eu.etaxonomy.cdm.model.location.Country;
47 import eu.etaxonomy.cdm.model.location.NamedArea;
48 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
49 import eu.etaxonomy.cdm.model.location.NamedAreaType;
50 import eu.etaxonomy.cdm.model.location.ReferenceSystem;
51 import eu.etaxonomy.cdm.model.media.Media;
52 import eu.etaxonomy.cdm.model.media.RightsType;
53 import eu.etaxonomy.cdm.model.metadata.NamedAreaSearchField;
54 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
55 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
56 import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
57 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
58 import eu.etaxonomy.cdm.model.name.Rank;
59 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
60 import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
61 import eu.etaxonomy.cdm.model.taxon.SynonymType;
62 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
63 import eu.etaxonomy.cdm.model.term.DefinedTerm;
64 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
65 import eu.etaxonomy.cdm.model.term.TermType;
66 import eu.etaxonomy.cdm.model.term.TermVocabulary;
67 import eu.etaxonomy.cdm.model.view.AuditEvent;
68 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
69 import eu.etaxonomy.cdm.persistence.dao.term.IDefinedTermDao;
70 import eu.etaxonomy.cdm.persistence.dto.FeatureDto;
71 import eu.etaxonomy.cdm.persistence.dto.TermDto;
72 import eu.etaxonomy.cdm.persistence.query.MatchMode;
73 import eu.etaxonomy.cdm.persistence.query.OrderHint;
74
75 /**
76 * @author a.kohlbecker
77 * @since 29.05.2008
78 */
79 @Repository
80 public class DefinedTermDaoImpl extends IdentifiableDaoBase<DefinedTermBase> implements IDefinedTermDao{
81 private static final Logger logger = Logger.getLogger(DefinedTermDaoImpl.class);
82
83 public DefinedTermDaoImpl() {
84 super(DefinedTermBase.class);
85 indexedClasses = new Class[25];
86 indexedClasses[0] = Rank.class;
87 indexedClasses[1] = AnnotationType.class;
88 indexedClasses[2] = ExtensionType.class;
89 indexedClasses[3] = Language.class;
90 indexedClasses[4] = MarkerType.class;
91 indexedClasses[5] = MeasurementUnit.class;
92 indexedClasses[6] = DefinedTerm.class;
93 indexedClasses[7] = PresenceAbsenceTerm.class;
94 indexedClasses[8] = State.class;
95 indexedClasses[9] = StatisticalMeasure.class;
96 indexedClasses[10] = TextFormat.class;
97 indexedClasses[11] = DerivationEventType.class;
98 indexedClasses[12] = NamedArea.class;
99 indexedClasses[13] = NamedAreaLevel.class;
100 indexedClasses[14] = NamedAreaType.class;
101 indexedClasses[15] = ReferenceSystem.class;
102 indexedClasses[16] = Country.class;
103 indexedClasses[17] = RightsType.class;
104 indexedClasses[18] = HybridRelationshipType.class;
105 indexedClasses[19] = NameRelationshipType.class;
106 indexedClasses[20] = NameTypeDesignationStatus.class;
107 indexedClasses[21] = NomenclaturalStatusType.class;
108 indexedClasses[22] = SpecimenTypeDesignationStatus.class;
109 indexedClasses[23] = SynonymType.class;
110 indexedClasses[24] = TaxonRelationshipType.class;
111 }
112
113 /**
114 * Searches by Label
115 */
116 @Override
117 public List<DefinedTermBase> findByTitle(String queryString) {
118 return findByTitle(queryString, null);
119 }
120
121 /**
122 * Searches by Label
123 */
124 @Override
125 public List<DefinedTermBase> findByTitle(String queryString, CdmBase sessionObject) {
126 checkNotInPriorView("DefinedTermDaoImpl.findByTitle(String queryString, CdmBase sessionObject)");
127 Session session = getSession();
128 if ( sessionObject != null ) {//attache the object to the session, TODO needed?
129 session.update(sessionObject);
130 }
131 Query query = session.createQuery("select term from DefinedTermBase term join fetch term.representations representation where representation.label = :label");
132 query.setParameter("label", queryString);
133 @SuppressWarnings({ "unchecked", "rawtypes" })
134 List<DefinedTermBase> result = query.list();
135 return result;
136
137 }
138
139 @Override
140 public List<DefinedTermBase> findByTitle(String queryString, MatchMode matchMode, int page, int pagesize, List<Criterion> criteria) {
141 //FIXME is query parametrised?
142 checkNotInPriorView("DefinedTermDaoImpl.findByTitle(String queryString, ITitledDao.MATCH_MODE matchMode, int page, int pagesize, List<Criterion> criteria)");
143 Criteria crit = getSession().createCriteria(type);
144 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
145 crit.setMaxResults(pagesize);
146 int firstItem = (page - 1) * pagesize + 1;
147 crit.setFirstResult(firstItem);
148 List<DefinedTermBase> results = crit.list();
149 return results;
150 }
151
152 @Override
153 public Country getCountryByIso(String iso3166) {
154 // If iso639 = "" query returns non-unique result. We prevent this here:
155 if (StringUtils.isBlank(iso3166) || iso3166.length()<2 || iso3166.length()>3) { return null; }
156 AuditEvent auditEvent = getAuditEventFromContext();
157 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
158 Query query = getSession().createQuery("from Country where iso3166_A2 = :isoCode OR idInVocabulary = :isoCode");
159 query.setParameter("isoCode", iso3166);
160 return (Country) query.uniqueResult();
161 } else {
162 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(Country.class,auditEvent.getRevisionNumber());
163 query.add(AuditEntity.property("iso3166_A2").eq(iso3166));
164 query.add(AuditEntity.property("idInVocabulary").eq(iso3166));
165 return (Country) query.getSingleResult();
166 }
167 }
168
169 @Override
170 public <T extends DefinedTermBase> List<T> getDefinedTermByRepresentationText(String text, Class<T> clazz ) {
171 return getDefinedTermByRepresentationText(text,clazz,null,null);
172 }
173
174 @Override
175 public <T extends DefinedTermBase> List<T> getDefinedTermByRepresentationText(String text, Class<T> clazz, Integer pageSize,Integer pageNumber) {
176 checkNotInPriorView("DefinedTermDaoImpl.getDefinedTermByRepresentationText(String text, Class<T> clazz, Integer pageSize,Integer pageNumber)");
177
178 Criteria criteria = getCriteria(clazz);
179
180 criteria.createAlias("representations", "r").add(Restrictions.like("r.text", text));
181
182 addPageSizeAndNumber(criteria, pageSize, pageNumber);
183
184 @SuppressWarnings("unchecked")
185 List<T> result = criteria.list();
186 return result;
187 }
188
189 @Override
190 public long countDefinedTermByRepresentationText(String text, Class<? extends DefinedTermBase> clazz) {
191 checkNotInPriorView("DefinedTermDaoImpl.countDefinedTermByRepresentationText(String text, Class<? extends DefinedTermBase> clazz)");
192 Criteria criteria = getCriteria(clazz);
193
194 criteria.createAlias("representations", "r").add(Restrictions.like("r.text", text));
195
196 criteria.setProjection(Projections.rowCount());
197
198 return (Long)criteria.uniqueResult();
199 }
200
201 @Override
202 public <T extends DefinedTermBase> List<T> getDefinedTermByIdInVocabulary(String label, UUID vocUuid, Class<T> clazz, Integer pageSize, Integer pageNumber) {
203 checkNotInPriorView("DefinedTermDaoImpl.getDefinedTermByIdInVocabulary(String label, UUID vocUuid, Class<T> clazz, Integer pageSize, Integer pageNumber)");
204
205 Criteria criteria = getCriteria(clazz);
206
207 criteria.createAlias("vocabulary", "voc")
208 .add(Restrictions.like("voc.uuid", vocUuid))
209 .add(Restrictions.like("idInVocabulary", label, org.hibernate.criterion.MatchMode.EXACT));
210
211 addPageSizeAndNumber(criteria, pageSize, pageNumber);
212
213 @SuppressWarnings("unchecked")
214 List<T> result = criteria.list();
215 return result;
216 }
217
218 @Override
219 public <T extends DefinedTermBase> List<T> getDefinedTermByRepresentationAbbrev(String text, Class<T> clazz, Integer pageSize,Integer pageNumber) {
220 checkNotInPriorView("DefinedTermDaoImpl.getDefinedTermByRepresentationAbbrev(String abbrev, Class<T> clazz, Integer pageSize,Integer pageNumber)");
221
222 Criteria criteria = getCriteria(clazz);
223
224 criteria.createAlias("representations", "r").add(Restrictions.like("r.abbreviatedLabel", text));
225
226 addPageSizeAndNumber(criteria, pageSize, pageNumber);
227
228 @SuppressWarnings("unchecked")
229 List<T> result = criteria.list();
230 return result;
231 }
232
233 @Override
234 public long countDefinedTermByRepresentationAbbrev(String text, Class<? extends DefinedTermBase> clazz) {
235 checkNotInPriorView("DefinedTermDaoImpl.countDefinedTermByRepresentationAbbrev(String abbrev, Class<? extends DefinedTermBase> clazz)");
236 Criteria criteria = getCriteria(clazz);
237
238 criteria.createAlias("representations", "r").add(Restrictions.like("r.abbreviatedLabel", text));
239 criteria.setProjection(Projections.rowCount());
240
241 return (Long)criteria.uniqueResult();
242 }
243
244 @Override
245 public Language getLanguageByIso(String iso639) {
246 if (iso639.length() < 2 || iso639.length() > 3) {
247 logger.warn("Invalid length " + iso639.length() + " of ISO code. Length must be 2 or 3.");
248 return null;
249 }
250 boolean isIso639_1 = iso639.length() == 2;
251
252 String queryStr;
253 if (isIso639_1){
254 queryStr = "from Language where iso639_1 = :isoCode";
255 }else{
256 queryStr = "from Language where idInVocabulary = :isoCode and vocabulary.uuid = :vocUuid";
257 }
258 AuditEvent auditEvent = getAuditEventFromContext();
259 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
260 Query query = getSession().createQuery(queryStr);
261 query.setParameter("isoCode", iso639);
262 if (! isIso639_1){
263 query.setParameter("vocUuid", Language.uuidLanguageVocabulary);
264 }
265 return (Language) query.uniqueResult();
266 } else {
267 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(Language.class,auditEvent.getRevisionNumber());
268 if (isIso639_1){
269 query.add(AuditEntity.property("iso639_1").eq(iso639));
270 }else{
271 query.add(AuditEntity.property("iso639_2").eq(iso639));
272 query.add(AuditEntity.property("vocabulary.uuid").eq(Language.uuidLanguageVocabulary));
273 }
274
275 return (Language)query.getSingleResult();
276 }
277 }
278
279 /**
280 * FIXME this will result in a query per language - could you, given that iso codes
281 * are unique, use from Language where iso639_1 in (:isoCode) or iso639_2 in (:isoCode)
282 */
283 @Override
284 public List<Language> getLanguagesByIso(List<String> iso639List) {
285 List<Language> languages = new ArrayList<Language>(iso639List.size());
286 for (String iso639 : iso639List) {
287 languages.add(getLanguageByIso(iso639));
288 }
289 return languages;
290 }
291
292 @Override
293 public List<Language> getLanguagesByLocale(Enumeration<Locale> locales) {
294 List<Language> languages = new ArrayList<Language>();
295 while(locales.hasMoreElements()) {
296 Locale locale = locales.nextElement();
297 languages.add(getLanguageByIso(locale.getLanguage()));
298 }
299 return languages;
300 }
301
302 @Override
303 public long count(NamedAreaLevel level, NamedAreaType type) {
304 AuditEvent auditEvent = getAuditEventFromContext();
305 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
306 Criteria criteria = getCriteria(NamedArea.class);
307
308 if(level != null) {
309 criteria.add(Restrictions.eq("level",level));
310 }
311
312 if(type != null) {
313 criteria.add(Restrictions.eq("type", type));
314 }
315
316 criteria.setProjection(Projections.rowCount());
317
318 return (Long)criteria.uniqueResult();
319 } else {
320 AuditQuery query = makeAuditQuery(NamedArea.class, auditEvent);
321
322 if(level != null) {
323 query.add(AuditEntity.relatedId("level").eq(level.getId()));
324 }
325
326 if(type != null) {
327 query.add(AuditEntity.relatedId("type").eq(type.getId()));
328 }
329 query.addProjection(AuditEntity.id().count());
330 return (Long)query.getSingleResult();
331 }
332 }
333
334 @Override
335 public long countMedia(DefinedTermBase definedTerm) {
336 checkNotInPriorView("DefinedTermDaoImpl.countMedia(DefinedTermBase definedTerm)");
337 Query query = getSession().createQuery("select count(media) from DefinedTermBase definedTerm join definedTerm.media media where definedTerm = :definedTerm");
338 query.setParameter("definedTerm", definedTerm);
339
340 return (Long)query.uniqueResult();
341 }
342
343 @Override
344 public List<Media> getMedia(DefinedTermBase definedTerm, Integer pageSize, Integer pageNumber) {
345 checkNotInPriorView("DefinedTermDaoImpl.getMedia(DefinedTermBase definedTerm, Integer pageSize, Integer pageNumber)");
346 Query query = getSession().createQuery("select media from DefinedTermBase definedTerm join definedTerm.media media where definedTerm = :definedTerm");
347 query.setParameter("definedTerm", definedTerm);
348
349 addPageSizeAndNumber(query, pageSize, pageNumber);
350
351 @SuppressWarnings("unchecked")
352 List<Media> result = query.list();
353 return result;
354 }
355
356 @Override
357 public List<NamedArea> list(NamedAreaLevel level, NamedAreaType type, Integer pageSize, Integer pageNumber) {
358 AuditEvent auditEvent = getAuditEventFromContext();
359 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
360 Criteria criteria = getCriteria(NamedArea.class);
361
362 if(level != null) {
363 criteria.add(Restrictions.eq("level",level));
364 }
365
366 if(type != null) {
367 criteria.add(Restrictions.eq("type", type));
368 }
369
370 addPageSizeAndNumber(criteria, pageSize, pageNumber);
371
372 @SuppressWarnings("unchecked")
373 List<NamedArea> result = criteria.list();
374 return result;
375 } else {
376 AuditQuery query = makeAuditQuery(NamedArea.class, auditEvent);
377
378 if(level != null) {
379 query.add(AuditEntity.relatedId("level").eq(level.getId()));
380 }
381
382 if(type != null) {
383 query.add(AuditEntity.relatedId("type").eq(type.getId()));
384 }
385
386 @SuppressWarnings("unchecked")
387 List<NamedArea> result = query.getResultList();
388 return result;
389 }
390 }
391
392 @Override
393 public List<NamedArea> list(NamedAreaLevel level, NamedAreaType type, Integer pageSize, Integer pageNumber,
394 List<OrderHint> orderHints, List<String> propertyPaths) {
395
396 List<NamedArea> result;
397
398 AuditEvent auditEvent = getAuditEventFromContext();
399 if (auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
400 Criteria criteria = getCriteria(NamedArea.class);
401
402 if (level != null) {
403 criteria.add(Restrictions.eq("level", level));
404 }
405 if (type != null) {
406 criteria.add(Restrictions.eq("type", type));
407 }
408 addOrder(criteria,orderHints);
409 addPageSizeAndNumber(criteria, pageSize, pageNumber);
410
411 result = criteria.list();
412
413 } else {
414 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(NamedArea.class,
415 auditEvent.getRevisionNumber());
416 if (level != null) {
417 query.add(AuditEntity.relatedId("level").eq(level.getId()));
418 }
419 if (type != null) {
420 query.add(AuditEntity.relatedId("type").eq(type.getId()));
421 }
422 result = query.getResultList();
423 }
424
425 defaultBeanInitializer.initializeAll(result, propertyPaths);
426
427 return result;
428 }
429
430
431 @Override
432 public <T extends DefinedTermBase> long countGeneralizationOf(T kindOf) {
433 AuditEvent auditEvent = getAuditEventFromContext();
434 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
435 Query query = getSession().createQuery("select count(term) from DefinedTermBase term where term.kindOf = :kindOf");
436 query.setParameter("kindOf", kindOf);
437 return (Long)query.uniqueResult();
438 } else {
439 AuditQuery query = makeAuditQuery(DefinedTermBase.class,auditEvent);
440 query.add(AuditEntity.relatedId("kindOf").eq(kindOf.getId()));
441 query.addProjection(AuditEntity.id().count());
442 return (Long)query.getSingleResult();
443 }
444 }
445
446 @Override
447 public <T extends DefinedTermBase> long countIncludes(Collection<T> partOf) {
448 if (partOf == null || partOf.isEmpty()){
449 return 0;
450 }
451 AuditEvent auditEvent = getAuditEventFromContext();
452 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
453 Query query = getSession().createQuery("select count(term) from DefinedTermBase term where term.partOf in (:partOf)");
454 query.setParameterList("partOf", partOf);
455 return (Long)query.uniqueResult();
456 } else {
457 long count = 0;
458 for(T t : partOf) {
459 AuditQuery query = makeAuditQuery(DefinedTermBase.class, auditEvent);
460 query.add(AuditEntity.relatedId("partOf").eq(t.getId()));
461 query.addProjection(AuditEntity.id().count());
462 count += (Long)query.getSingleResult();
463 }
464 return count;
465 }
466 }
467
468 @Override
469 public <T extends DefinedTermBase> List<T> getGeneralizationOf(T kindOf, Integer pageSize, Integer pageNumber) {
470 AuditEvent auditEvent = getAuditEventFromContext();
471 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
472 Query query = getSession().createQuery("select term from DefinedTermBase term where term.kindOf = :kindOf");
473 query.setParameter("kindOf", kindOf);
474
475 addPageSizeAndNumber(query, pageSize, pageNumber);
476
477 @SuppressWarnings("unchecked")
478 List<T> result = query.list();
479 return result;
480 } else {
481 AuditQuery query = makeAuditQuery(DefinedTermBase.class, auditEvent);
482 query.add(AuditEntity.relatedId("kindOf").eq(kindOf.getId()));
483
484 addPageSizeAndNumber(query, pageSize, pageNumber);
485
486 @SuppressWarnings("unchecked")
487 List<T> result = query.getResultList();
488 return result;
489 }
490 }
491
492 @Override
493 public <T extends DefinedTermBase> List<T> getIncludes(Collection<T> partOf, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
494 if (partOf == null || partOf.isEmpty()){
495 return new ArrayList<>();
496 }
497 AuditEvent auditEvent = getAuditEventFromContext();
498 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
499 Query query = getSession().createQuery("select term from DefinedTermBase term where term.partOf in (:partOf)");
500 query.setParameterList("partOf", partOf);
501
502 addPageSizeAndNumber(query, pageSize, pageNumber);
503
504 @SuppressWarnings("unchecked")
505 List<T> results = query.list();
506 defaultBeanInitializer.initializeAll(results, propertyPaths);
507 return results;
508 } else {
509 List<T> result = new ArrayList<T>();
510 for(T t : partOf) {
511 AuditQuery query = makeAuditQuery(DefinedTermBase.class, auditEvent);
512 query.add(AuditEntity.relatedId("partOf").eq(t.getId()));
513 addPageSizeAndNumber(query, pageSize, pageNumber);
514
515 result.addAll(query.getResultList());
516 }
517 defaultBeanInitializer.initializeAll(result, propertyPaths);
518 return result;
519 }
520 }
521
522 @Override
523 public <T extends DefinedTermBase> long countPartOf(Set<T> definedTerms) {
524 checkNotInPriorView("DefinedTermDaoImpl.countPartOf(Set<T> definedTerms)");
525 Query query = getSession().createQuery("select count(distinct definedTerm) from DefinedTermBase definedTerm join definedTerm.includes included where included in (:definedTerms)");
526 query.setParameterList("definedTerms", definedTerms);
527 return (Long)query.uniqueResult();
528 }
529
530 @Override
531 public <T extends DefinedTermBase> List<T> getPartOf(Set<T> definedTerms, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
532 checkNotInPriorView("DefinedTermDaoImpl.getPartOf(Set<T> definedTerms, Integer pageSize, Integer pageNumber)");
533 Query query = getSession().createQuery("select distinct definedTerm from DefinedTermBase definedTerm join definedTerm.includes included where included in (:definedTerms)");
534 query.setParameterList("definedTerms", definedTerms);
535
536 addPageSizeAndNumber(query, pageSize, pageNumber);
537
538 @SuppressWarnings("unchecked")
539 List<T> r = query.list();
540 /**
541 * For some weird reason, hibernate returns proxies (extending the superclass), not the actual class on this,
542 * despite querying the damn database and returning the discriminator along with the rest of the object properties!
543 *
544 * Probably a bug in hibernate, but we'll manually deproxy for now since the objects are initialized anyway, the
545 * performance implications are small (we're swapping one array of references for another, not hitting the db or
546 * cache).
547 */
548 List<T> results = new ArrayList<>();
549 if(!definedTerms.isEmpty()) {
550 for(T t : r) {
551 T deproxied = CdmBase.deproxy(t);
552 results.add(deproxied);
553 }
554 defaultBeanInitializer.initializeAll(results, propertyPaths);
555 }
556 return results;
557 }
558
559 @Override
560 public DefinedTermBase findByUri(URI uri) {
561 AuditEvent auditEvent = getAuditEventFromContext();
562 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
563 Query query = getSession().createQuery("select term from DefinedTermBase term where term.uri = :uri");
564 query.setParameter("uri", uri);
565 return (DefinedTermBase<?>)query.uniqueResult();
566 } else {
567 AuditQuery query = makeAuditQuery(DefinedTermBase.class, auditEvent);
568 query.add(AuditEntity.property("uri").eq(uri));
569 return (DefinedTermBase<?>)query.getSingleResult();
570 }
571 }
572
573 @Override
574 public <T extends DefinedTermBase> List<T> listByTermType(TermType termType, Integer limit, Integer start,
575 List<OrderHint> orderHints, List<String> propertyPaths) {
576 Query query = getSession().createQuery("SELECT term FROM DefinedTermBase term WHERE term.termType = :termType");
577 query.setParameter("termType", termType);
578
579 @SuppressWarnings("unchecked")
580 List<T> result = query.list();
581
582 defaultBeanInitializer.initializeAll(result, propertyPaths);
583 return result;
584 }
585
586 @Override
587 public <TERM extends DefinedTermBase> List<TERM> listByTermClass(Class<TERM> clazz, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
588 // checkNotInPriorView("DefinedTermDaoImpl.listByTermClass(Class<TERM> clazz, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)");
589
590 Query query = getSession().createQuery("FROM " + clazz.getSimpleName());
591
592 @SuppressWarnings("unchecked")
593 List<TERM> result = query.list();
594
595 defaultBeanInitializer.initializeAll(result, propertyPaths);
596
597 return result;
598 }
599
600 @Override
601 public <S extends DefinedTermBase> List<S> list(Class<S> type, Integer limit, Integer start,
602 List<OrderHint> orderHints, List<String> propertyPath) {
603
604 return deduplicateResult(super.list(type, limit, start, orderHints, propertyPath));
605 }
606
607 /**
608 * Workaround for http://dev.e-taxonomy.eu/trac/ticket/5871 and #5945
609 * Terms with multiple representations return identical duplicates
610 * due to eager representation loading. We expect these duplicates to appear
611 * in line wo we only compare one term with its predecessor. If it already
612 * exists we remove it from the result.
613 * @param orginals
614 * @return
615 */
616 private <S extends DefinedTermBase<?>> List<S> deduplicateResult(List<S> orginals) {
617 List<S> result = new ArrayList<>();
618 Iterator<S> it = orginals.iterator();
619 S last = null;
620 while (it.hasNext()){
621 S a = it.next();
622 if (a != last){
623 if (!result.contains(a)){
624 result.add(a);
625 }
626 }
627 last = a;
628 }
629 return result;
630 }
631
632 @Override
633 public List<NamedArea> listNamedArea(List<TermVocabulary> vocs, Integer pageNumber, Integer limit, String pattern, MatchMode matchmode){
634 Session session = getSession();
635 // Query query = null;
636 // if (pattern != null){
637 // if (vocs != null && !vocs.isEmpty()){
638 // query = session.createQuery("from NamedArea where titleCache like :pattern and vocabulary in :vocs ORDER BY titleCache");
639 // query.setParameterList("vocs", vocs);
640 // }else{
641 // query = session.createQuery("from NamedArea where titleCache like :pattern ORDER BY titleCache");
642 // }
643 // pattern = pattern.replace("*", "%");
644 // pattern = pattern.replace("?", "_");
645 // pattern = pattern + "%";
646 // query.setParameter("pattern", pattern);
647 //
648 // } else {
649 // query = session.createQuery("FROM NamedArea WHERE vocabulary IN :vocs ORDER BY titleCache");
650 // query.setParameterList("vocs", vocs);
651 // }
652 // if (limit != null && limit > 0){
653 // query.setMaxResults(limit);
654 // }
655
656 Criteria crit = getSession().createCriteria(type, "namedArea");
657 if (!StringUtils.isBlank(pattern)){
658 if (matchmode == MatchMode.EXACT) {
659 crit.add(Restrictions.eq("titleCache", matchmode.queryStringFrom(pattern)));
660 } else {
661 // crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
662 crit.add(Restrictions.like("titleCache", matchmode.queryStringFrom(pattern)));
663 }
664 }
665 if (limit != null && limit >= 0) {
666 crit.setMaxResults(limit);
667 }
668
669 if (vocs != null &&!vocs.isEmpty()){
670 crit.createAlias("namedArea.vocabulary", "voc");
671 Disjunction or = Restrictions.disjunction();
672 for (TermVocabulary<?> voc: vocs){
673 Criterion criterion = Restrictions.eq("voc.id", voc.getId());
674 or.add(criterion);
675 }
676 crit.add(or);
677 }
678
679 crit.addOrder(Order.asc("titleCache"));
680 if (limit == null){
681 limit = 1;
682 }
683 // int firstItem = (pageNumber - 1) * limit;
684
685 crit.setFirstResult(0);
686 @SuppressWarnings("unchecked")
687 List<NamedArea> results = crit.list();
688 return results;
689 }
690
691
692 @Override
693 public List<NamedArea> listNamedAreaByAbbrev(List<TermVocabulary> vocs, Integer pageNumber, Integer limit, String pattern, MatchMode matchmode, NamedAreaSearchField abbrevType){
694
695 Criteria crit = getSession().createCriteria(type, "namedArea");
696 if (!StringUtils.isBlank(pattern)){
697 if (matchmode == MatchMode.EXACT) {
698 crit.add(Restrictions.eq(abbrevType.getKey(), matchmode.queryStringFrom(pattern)));
699 } else {
700 // crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
701 crit.add(Restrictions.like(abbrevType.getKey(), matchmode.queryStringFrom(pattern)));
702 }
703 }
704 if (limit != null && limit >= 0) {
705 crit.setMaxResults(limit);
706 }
707
708 if (vocs != null &&!vocs.isEmpty()){
709 crit.createAlias("namedArea.vocabulary", "voc");
710 Disjunction or = Restrictions.disjunction();
711 for (TermVocabulary<?> voc: vocs){
712 Criterion criterion = Restrictions.eq("voc.id", voc.getId());
713 or.add(criterion);
714 }
715 crit.add(or);
716 }
717
718 crit.addOrder(Order.asc(abbrevType.getKey()));
719 if (limit == null){
720 limit = 1;
721 }
722 // int firstItem = (pageNumber - 1) * limit;
723
724 crit.setFirstResult(0);
725 @SuppressWarnings("unchecked")
726 List<NamedArea> results = crit.list();
727 return results;
728 }
729
730 @Override
731 public long count(List<TermVocabulary> vocs, String pattern){
732 Session session = getSession();
733 Query query = null;
734 if (pattern != null){
735 if (vocs != null && !vocs.isEmpty()){
736 query = session.createQuery("SELECT COUNT(*) FROM NamedArea WHERE titleCache LIKE :pattern AND vocabulary IN :vocs");
737 query.setParameterList("vocs", vocs);
738 }else{
739 query = session.createQuery("SELECT COUNT(*) FROM NamedArea WHERE titleCache LIKE :pattern ");
740 }
741 pattern = pattern.replace("*", "%");
742 pattern = pattern.replace("?", "_");
743 pattern = pattern + "%";
744 query.setParameter("pattern", pattern);
745
746 } else {
747 query = session.createQuery("SELECT COUNT(*) FROM NamedArea WHERE vocabulary IN :vocs");
748 query.setParameterList("vocs", vocs);
749 }
750
751 Long result = (Long) query.uniqueResult();
752 return result;
753 }
754
755 @Override
756 public Collection<TermDto> getIncludesAsDto(
757 TermDto parentTerm) {
758 String queryString;
759 if (parentTerm.getTermType().equals(TermType.NamedArea)){
760 queryString = TermDto.getTermDtoSelectNamedArea();
761 }else{
762 queryString = TermDto.getTermDtoSelect();
763 }
764 queryString = queryString
765 + "where a.partOf.uuid = :parentUuid";
766 Query query = getSession().createQuery(queryString);
767 query.setParameter("parentUuid", parentTerm.getUuid());
768
769 @SuppressWarnings("unchecked")
770 List<Object[]> result = query.list();
771
772 List<TermDto> list = TermDto.termDtoListFrom(result);
773 return list;
774 }
775
776 @Override
777 public Collection<TermDto> getKindOfsAsDto(
778 TermDto parentTerm) {
779 String queryString;
780 if (parentTerm.getTermType().equals(TermType.NamedArea)){
781 queryString = TermDto.getTermDtoSelectNamedArea();
782 }else{
783 queryString = TermDto.getTermDtoSelect();
784 }
785 queryString = queryString + "where a.kindOf.uuid = :parentUuid";
786 Query query = getSession().createQuery(queryString);
787 query.setParameter("parentUuid", parentTerm.getUuid());
788
789 @SuppressWarnings("unchecked")
790 List<Object[]> result = query.list();
791
792 List<TermDto> list = TermDto.termDtoListFrom(result);
793 return list;
794 }
795
796 @Override
797 public Collection<TermDto> findByTitleAsDto(String title, TermType termType) {
798 String queryString = TermDto.getTermDtoSelect()
799 + " where a.titleCache like :title "
800 + (termType!=null?" and a.termType = :termType ":"");
801
802 title = title.replace("*", "%");
803 Query query = getSession().createQuery(queryString);
804 query.setParameter("title", "%"+title+"%");
805 if(termType!=null){
806 query.setParameter("termType", termType);
807 }
808
809 @SuppressWarnings("unchecked")
810 List<Object[]> result = query.list();
811
812 List<TermDto> list = TermDto.termDtoListFrom(result);
813 return list;
814 }
815
816 @Override
817 public Collection<TermDto> findByTypeAsDto(TermType termType) {
818 if (termType == null){
819 return null;
820 }
821 String queryString = TermDto.getTermDtoSelect()
822 + " where a.termType = :termType ";
823 Query query = getSession().createQuery(queryString);
824
825 if(termType!=null){
826 query.setParameter("termType", termType);
827 }
828
829 @SuppressWarnings("unchecked")
830 List<Object[]> result = query.list();
831
832 List<TermDto> list = TermDto.termDtoListFrom(result);
833 return list;
834 }
835
836 @Override
837 public Collection<TermDto> findByUriAsDto(URI uri, String termLabel, TermType termType) {
838 String queryString = TermDto.getTermDtoSelect()
839 + " where a.uri like :uri "
840 + (termType!=null?" and a.termType = :termType ":"")
841 + (termLabel!=null?" and a.titleCache = :termLabel ":"")
842 ;
843 Query query = getSession().createQuery(queryString);
844 query.setParameter("uri", uri.toString());
845 if(termLabel!=null){
846 query.setParameter("termLabel", "%"+termLabel+"%");
847 }
848 if(termType!=null){
849 query.setParameter("termType", termType);
850 }
851
852 @SuppressWarnings("unchecked")
853 List<Object[]> result = query.list();
854
855 List<TermDto> list = TermDto.termDtoListFrom(result);
856 return list;
857 }
858
859 @Override
860 public List<NamedArea> listNamedArea(List<TermVocabulary> vocs, Integer limit, String pattern) {
861
862 return listNamedArea(vocs, 0, limit, pattern, MatchMode.BEGINNING);
863 }
864
865 @Override
866 public List<NamedArea> listNamedAreaByAbbrev(List<TermVocabulary> vocs, Integer limit, String pattern, NamedAreaSearchField type) {
867
868 return listNamedAreaByAbbrev(vocs, 0, limit, pattern, MatchMode.BEGINNING, type);
869 }
870
871 @Override
872 public List<TermDto> getSupportedStatesForFeature(UUID featureUuid){
873 List<TermDto> list = new ArrayList<>();
874 String supportedCategoriesQueryString = "SELECT cat.uuid "
875 + "from DefinedTermBase t "
876 + "join t.supportedCategoricalEnumerations as cat "
877 + "where t.uuid = :featureUuid";
878 Query supportedCategoriesQuery = getSession().createQuery(supportedCategoriesQueryString);
879 supportedCategoriesQuery.setParameter("featureUuid", featureUuid);
880 @SuppressWarnings("unchecked")
881 List<UUID> supportedCategories = supportedCategoriesQuery.list();
882 if(supportedCategories.isEmpty()){
883 return list;
884 }
885
886 String queryString = TermDto.getTermDtoSelect()
887 + "where v.uuid in (:supportedCategories) "
888 + "order by a.titleCache";
889 Query query = getSession().createQuery(queryString);
890 query.setParameterList("supportedCategories", supportedCategories);
891
892 @SuppressWarnings("unchecked")
893 List<Object[]> result = query.list();
894
895 list = TermDto.termDtoListFrom(result);
896 return list;
897 }
898
899 @Override
900 public Collection<TermDto> findByUUIDsAsDto(List<UUID> uuidList) {
901 List<TermDto> list = new ArrayList<>();
902 if (uuidList == null || uuidList.isEmpty()){
903 return null;
904 }
905
906 String queryString = TermDto.getTermDtoSelect()
907 + "where a.uuid in :uuidList "
908 + "order by a.titleCache";
909 Query query = getSession().createQuery(queryString);
910 query.setParameterList("uuidList", uuidList);
911
912 @SuppressWarnings("unchecked")
913 List<Object[]> result = query.list();
914
915 list = TermDto.termDtoListFrom(result);
916 return list;
917 }
918
919 @Override
920 public Collection<TermDto> findFeatureByUUIDsAsDto(List<UUID> uuidList) {
921 List<TermDto> list = new ArrayList<>();
922 if (uuidList == null || uuidList.isEmpty()){
923 return null;
924 }
925
926 String queryString = FeatureDto.getTermDtoSelect()
927 + "where a.uuid in :uuidList "
928 + "order by a.titleCache";
929 Query query = getSession().createQuery(queryString);
930 query.setParameterList("uuidList", uuidList);
931
932 @SuppressWarnings("unchecked")
933 List<Object[]> result = query.list();
934
935 list = FeatureDto.termDtoListFrom(result);
936 return list;
937 }
938
939 @Override
940 public Collection<TermDto> findFeatureByTitleAsDto(String pattern) {
941 String queryString = FeatureDto.getTermDtoSelect()
942 + " where a.titleCache like :title "
943 + " and a.termType = :termType ";
944
945 pattern = pattern.replace("*", "%");
946 Query query = getSession().createQuery(queryString);
947 query.setParameter("title", "%"+pattern+"%");
948 query.setParameter("termType", TermType.Feature);
949
950
951 @SuppressWarnings("unchecked")
952 List<Object[]> result = query.list();
953
954 List<TermDto> list = FeatureDto.termDtoListFrom(result);
955 return list;
956 }
957
958 }