fixed the error if a taxon has no synonyms
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / taxon / TaxonDaoHibernateImpl.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 package eu.etaxonomy.cdm.persistence.dao.hibernate.taxon;
10
11 import java.lang.reflect.Field;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Comparator;
15 import java.util.HashSet;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Set;
19 import java.util.SortedSet;
20 import java.util.TreeSet;
21 import java.util.UUID;
22
23 import org.apache.log4j.Logger;
24 import org.apache.lucene.analysis.SimpleAnalyzer;
25 import org.apache.lucene.queryParser.ParseException;
26 import org.apache.lucene.queryParser.QueryParser;
27 import org.hibernate.Criteria;
28 import org.hibernate.FetchMode;
29 import org.hibernate.Hibernate;
30 import org.hibernate.Query;
31 import org.hibernate.criterion.Criterion;
32 import org.hibernate.criterion.Projections;
33 import org.hibernate.criterion.Restrictions;
34 import org.hibernate.envers.query.AuditEntity;
35 import org.hibernate.envers.query.AuditQuery;
36 import org.hibernate.search.FullTextSession;
37 import org.hibernate.search.Search;
38 import org.hibernate.search.SearchFactory;
39 import org.springframework.beans.factory.annotation.Autowired;
40 import org.springframework.beans.factory.annotation.Qualifier;
41 import org.springframework.dao.DataAccessException;
42 import org.springframework.stereotype.Repository;
43 import org.springframework.util.ReflectionUtils;
44
45 import eu.etaxonomy.cdm.model.common.Annotation;
46 import eu.etaxonomy.cdm.model.common.Extension;
47 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
48 import eu.etaxonomy.cdm.model.common.LSID;
49 import eu.etaxonomy.cdm.model.common.Marker;
50 import eu.etaxonomy.cdm.model.common.RelationshipBase;
51 import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
52 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
53 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
54 import eu.etaxonomy.cdm.model.description.TaxonDescription;
55 import eu.etaxonomy.cdm.model.location.NamedArea;
56 import eu.etaxonomy.cdm.model.media.Rights;
57 import eu.etaxonomy.cdm.model.name.Rank;
58 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
59 import eu.etaxonomy.cdm.model.taxon.Synonym;
60 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
61 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
62 import eu.etaxonomy.cdm.model.taxon.Taxon;
63 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
64 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
65 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
66 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
67 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
68 import eu.etaxonomy.cdm.model.view.AuditEvent;
69 import eu.etaxonomy.cdm.persistence.dao.QueryParseException;
70 import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;
71 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
72 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
73 import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;
74 import eu.etaxonomy.cdm.persistence.query.MatchMode;
75 import eu.etaxonomy.cdm.persistence.query.OrderHint;
76
77
78 /**
79 * @author a.mueller
80 * @created 24.11.2008
81 * @version 1.0
82 */
83 @Repository
84 @Qualifier("taxonDaoHibernateImpl")
85 public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implements ITaxonDao {
86 private AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser;
87 private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);
88
89 private String defaultField = "name.titleCache";
90 private Class<? extends TaxonBase> indexedClasses[];
91
92 public TaxonDaoHibernateImpl() {
93 super(TaxonBase.class);
94 indexedClasses = new Class[2];
95 indexedClasses[0] = Taxon.class;
96 indexedClasses[1] = Synonym.class;
97 }
98
99 @Autowired(required = false) //TODO switched of because it caused problems when starting CdmApplicationController
100 public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser) {
101 this.alternativeSpellingSuggestionParser = alternativeSpellingSuggestionParser;
102 }
103
104
105 /* (non-Javadoc)
106 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)
107 */
108 public List<Taxon> getRootTaxa(ReferenceBase sec) {
109 return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);
110 }
111
112 /* (non-Javadoc)
113 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.ReferenceBase, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)
114 */
115 public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications, List<String> propertyPaths) {
116 checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");
117 if (onlyWithChildren == null){
118 onlyWithChildren = true;
119 }
120 if (withMisapplications == null){
121 withMisapplications = true;
122 }
123 if (cdmFetch == null){
124 cdmFetch = CdmFetch.NO_FETCH();
125 }
126
127 Criteria crit = getSession().createCriteria(Taxon.class);
128
129 crit.setFetchMode("name", FetchMode.JOIN);
130 crit.createAlias("name", "name");
131
132 if (rank != null) {
133 crit.add(Restrictions.eq("name.rank", rank));
134 }else{
135 crit.add(Restrictions.isNull("taxonomicParentCache"));
136 }
137
138 if (sec != null){
139 crit.add(Restrictions.eq("sec", sec) );
140 }
141
142 if (! cdmFetch.includes(CdmFetch.FETCH_CHILDTAXA())){
143 logger.info("Not fetching child taxa");
144 //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)
145 crit.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode.LAZY);
146 }
147
148 List<Taxon> results = new ArrayList<Taxon>();
149 List<Taxon> taxa = crit.list();
150 for(Taxon taxon : taxa){
151
152
153 //childTaxa
154 //TODO create restriction instead
155 // (a) not using cache fields
156 /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());
157 if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){
158 if (withMisapplications == true || ! taxon.isMisappliedName()){
159 defaultBeanInitializer.initialize(taxon, propertyPaths);
160 results.add(taxon);
161 }
162 }*/
163 // (b) using cache fields
164 if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){
165 if (withMisapplications == true || ! taxon.isMisappliedName()){
166 defaultBeanInitializer.initialize(taxon, propertyPaths);
167 results.add(taxon);
168 }
169 }
170 }
171 return results;
172 }
173
174 /* (non-Javadoc)
175 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)
176 */
177 public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {
178 return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications, null);
179 }
180
181
182 public List<TaxonBase> getTaxaByName(String queryString, ReferenceBase sec) {
183
184 return getTaxaByName(queryString, true, sec);
185 }
186
187 public List<TaxonBase> getTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
188 checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, ReferenceBase sec)");
189
190 Criteria criteria = null;
191 if (accepted == true) {
192 criteria = getSession().createCriteria(Taxon.class);
193 } else {
194 criteria = getSession().createCriteria(Synonym.class);
195 }
196
197 criteria.setFetchMode( "name", FetchMode.JOIN );
198 criteria.createAlias("name", "name");
199
200 if (sec != null && sec.getId() != 0) {
201 criteria.add(Restrictions.eq("sec", sec ) );
202 }
203
204 if (queryString != null) {
205 criteria.add(Restrictions.ilike("name.nameCache", queryString));
206 }
207
208 return (List<TaxonBase>)criteria.list();
209 }
210
211 public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, MatchMode matchMode,
212 Integer pageSize, Integer pageNumber) {
213
214 return getTaxaByName(clazz, queryString, null, matchMode, null, pageSize, pageNumber, null);
215 }
216
217 public List<TaxonBase> getTaxaByName(String queryString, MatchMode matchMode,
218 Boolean accepted, Integer pageSize, Integer pageNumber) {
219
220 if (accepted == true) {
221 return getTaxaByName(Taxon.class, queryString, matchMode, pageSize, pageNumber);
222 } else {
223 return getTaxaByName(Synonym.class, queryString, matchMode, pageSize, pageNumber);
224 }
225 }
226
227
228 public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, TaxonomicTree taxonomicTree,
229 MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize,
230 Integer pageNumber, List<String> propertyPaths) {
231
232 boolean doCount = false;
233 Query query = prepareTaxaByName(clazz, queryString, taxonomicTree, matchMode, namedAreas, pageSize, pageNumber, doCount);
234 if (query != null){
235 List<TaxonBase> results = query.list();
236 defaultBeanInitializer.initializeAll(results, propertyPaths);
237 return results;
238 }
239 return new ArrayList<TaxonBase>();
240
241 }
242
243 /**
244 * @param clazz
245 * @param queryString
246 * @param taxonomicTree TODO
247 * @param matchMode
248 * @param namedAreas
249 * @param pageSize
250 * @param pageNumber
251 * @param doCount
252 * @return
253 *
254 * FIXME implement taxontree restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}
255 */
256 private Query prepareTaxaByName(Class<? extends TaxonBase> clazz, String queryString, TaxonomicTree taxonomicTree,
257 MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount) {
258
259 //TODO ? checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec)");
260
261 String hqlQueryString = matchMode.queryStringFrom(queryString);
262
263 String matchOperator;
264 if (matchMode == MatchMode.EXACT) {
265 matchOperator = "=";
266 } else {
267 matchOperator = "like";
268 }
269
270 String selectWhat = (doCount ? "count(t)": "t");
271
272 String hql = "";
273 Set<NamedArea> areasExpanded = new HashSet<NamedArea>();
274 if(namedAreas != null && namedAreas.size() > 0){
275 // expand areas and restrict by distribution area
276 List<NamedArea> childAreas;
277 Query areaQuery = getSession().createQuery("select childArea from NamedArea as childArea left join childArea.partOf as parentArea where parentArea = :area");
278 expandNamedAreas(namedAreas, areasExpanded, areaQuery);
279 }
280 boolean doAreaRestriction = areasExpanded.size() > 0;
281
282 String taxonSubselect = null;
283 String synonymSubselect = null;
284
285 if(taxonomicTree != null){
286
287 if(doAreaRestriction){
288
289 taxonSubselect = "select t from" +
290 " Distribution e" +
291 " join e.inDescription d" +
292 " join d.taxon t" +
293 " join t.name n " +
294 " join t.taxonNodes as tn "+
295 " where" +
296 " e.area in (:namedAreas) AND" +
297 " tn.taxonomicTree = :taxonomicTree" +
298 " AND n.nameCache " + matchOperator + " :queryString";
299
300 synonymSubselect = "select s from" +
301 " Distribution e" +
302 " join e.inDescription d" +
303 " join d.taxon t" + // the taxa
304 " join t.taxonNodes as tn "+
305 " join t.synonymRelations sr" +
306 " join sr.relatedFrom s" + // the synonyms
307 " join s.name sn"+
308 " where" +
309 " e.area in (:namedAreas) AND" +
310 " tn.taxonomicTree = :taxonomicTree" +
311 " AND sn.nameCache " + matchOperator + " :queryString";
312
313 } else {
314
315 taxonSubselect = "select t from" +
316 " Taxon t" +
317 " join t.name n " +
318 " join t.taxonNodes as tn "+
319 " where" +
320 " tn.taxonomicTree = :taxonomicTree" +
321 " AND n.nameCache " + matchOperator + " :queryString";
322
323 synonymSubselect = "select s from" +
324 " Taxon t" + // the taxa
325 " join t.taxonNodes as tn "+
326 " join t.synonymRelations sr" +
327 " join sr.relatedFrom s" + // the synonyms
328 " join s.name sn"+
329 " where" +
330 " tn.taxonomicTree = :taxonomicTree" +
331 " AND sn.nameCache " + matchOperator + " :queryString";
332 }
333 } else {
334
335 if(doAreaRestriction){
336
337 taxonSubselect = "select t from " +
338 " Distribution e" +
339 " join e.inDescription d" +
340 " join d.taxon t" +
341 " join t.name n "+
342 " where" +
343 (doAreaRestriction ? " e.area in (:namedAreas) AND" : "") +
344 " n.nameCache " + matchOperator + " :queryString";
345
346 synonymSubselect = "select s from" +
347 " Distribution e" +
348 " join e.inDescription d" +
349 " join d.taxon t" + // the taxa
350 " join t.synonymRelations sr" +
351 " join sr.relatedFrom s" + // the synonyms
352 " join s.name sn"+
353 " where" +
354 (doAreaRestriction ? " e.area in (:namedAreas) AND" : "") +
355 " sn.nameCache " + matchOperator + " :queryString";
356
357 } else {
358
359 taxonSubselect = "select t from " +
360 " Taxon t" +
361 " join t.name n "+
362 " where" +
363 " n.nameCache " + matchOperator + " :queryString";
364
365 synonymSubselect = "select s from" +
366 " Taxon t" + // the taxa
367 " join t.synonymRelations sr" +
368 " join sr.relatedFrom s" + // the synonyms
369 " join s.name sn"+
370 " where" +
371 " sn.nameCache " + matchOperator + " :queryString";
372 }
373 }
374
375 // TODO mysql needs optimization: see http://www.xaprb.com/blog/2006/04/30/how-to-optimize-subqueries-and-joins-in-mysql/#commen
376 Query subTaxon = null;
377 Query subSynonym = null;
378 if(clazz.equals(Taxon.class)){
379 // find Taxa
380 subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);;
381 if(doAreaRestriction){
382 subTaxon.setParameterList("namedAreas", areasExpanded);
383 }
384 if(taxonomicTree != null){
385 subTaxon.setParameter("taxonomicTree", taxonomicTree);
386 }
387 } else if(clazz.equals(Synonym.class)){
388 // find synonyms
389 subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);;
390
391 if(doAreaRestriction){
392 subSynonym.setParameterList("namedAreas", areasExpanded);
393 }
394 if(taxonomicTree != null){
395 subSynonym.setParameter("taxonomicTree", taxonomicTree);
396 }
397 } else {
398 // find taxa and synonyms
399 subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);;
400 subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);;
401 if(doAreaRestriction){
402 subTaxon.setParameterList("namedAreas", areasExpanded);
403 subSynonym.setParameterList("namedAreas", areasExpanded);
404 }
405 if(taxonomicTree != null){
406 subTaxon.setParameter("taxonomicTree", taxonomicTree);
407 subSynonym.setParameter("taxonomicTree", taxonomicTree);
408 }
409 }
410
411 List<TaxonBase> taxa = null;
412 List<TaxonBase> synonyms = null;
413 if(clazz.equals(Taxon.class)){
414 taxa = subTaxon.list();
415 System.err.println("number of taxa: " +taxa.size());
416 }else if (clazz.equals(Synonym.class)){
417 System.err.println(subSynonym.getQueryString());
418 synonyms = subSynonym.list();
419 System.err.println("number of synonyms: " +synonyms.size());
420 }else {
421 System.err.println(subTaxon.getQueryString());
422 taxa = subTaxon.list();
423 System.err.println("number of taxa: " +taxa.size());
424 synonyms = subSynonym.list();
425 System.err.println("number of synonyms: " +synonyms.size());
426 }
427 if(clazz.equals(Taxon.class)){
428 if (taxa.size()>0){
429 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t in (:taxa)";
430 }else{
431 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
432 }
433 } else if(clazz.equals(Synonym.class) ){
434 if (synonyms.size()>0){
435 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t in (:synonyms)";
436 }else{
437 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
438 }
439 } else {
440 if(synonyms.size()>0 && taxa.size()>0){
441 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t in (:taxa) OR t in (:synonyms)";
442 }else if (synonyms.size()>0 ){
443 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t"
444 + " where t in (:synonyms)";
445 } else if (taxa.size()>0 ){
446 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t in (:taxa) ";
447 } else{
448 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
449 }
450 }
451
452 if (hql == "") return null;
453 if(!doCount){
454 hql += " order by t.titleCache"; //" order by t.name.nameCache";
455 }
456
457 Query query = getSession().createQuery(hql);
458
459 if(clazz.equals(Taxon.class) && taxa.size()>0){
460 //find taxa
461 query.setParameterList("taxa", taxa );
462 } else if(clazz.equals(Synonym.class) && synonyms.size()>0){
463 // find synonyms
464 query.setParameterList("synonyms", synonyms);
465
466
467 } else {
468 // find taxa and synonyms
469 if (taxa.size()>0)
470 query.setParameterList("taxa", taxa);
471 if (synonyms.size()>0)
472 query.setParameterList("synonyms",synonyms);
473 }
474
475 System.err.println("query: " +query.getQueryString());
476 if(pageSize != null && !doCount) {
477 query.setMaxResults(pageSize);
478 if(pageNumber != null) {
479 query.setFirstResult(pageNumber * pageSize);
480 }
481 }
482
483 return query;
484 }
485
486 /* (non-Javadoc)
487 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode, eu.etaxonomy.cdm.model.reference.ReferenceBase, java.util.Set)
488 */
489 public long countTaxaByName(Class<? extends TaxonBase> clazz, String queryString, TaxonomicTree taxonomicTree,
490 MatchMode matchMode, Set<NamedArea> namedAreas) {
491
492 boolean doCount = true;
493 Query query = prepareTaxaByName(clazz, queryString, taxonomicTree, matchMode, namedAreas, null, null, doCount);
494 if (query != null) {
495 return (Long)query.uniqueResult();
496 }
497 return 0;
498
499 }
500
501 /**
502 * @param namedAreas
503 * @param areasExpanded
504 * @param areaQuery
505 */
506 private void expandNamedAreas(Collection<NamedArea> namedAreas, Set<NamedArea> areasExpanded, Query areaQuery) {
507 List<NamedArea> childAreas;
508 for(NamedArea a : namedAreas){
509 areasExpanded.add(a);
510 areaQuery.setParameter("area", a);
511 childAreas = areaQuery.list();
512 if(childAreas.size() > 0){
513 areasExpanded.addAll(childAreas);
514 expandNamedAreas(childAreas, areasExpanded, areaQuery);
515 }
516 }
517 }
518
519 // /* (non-Javadoc)
520 // * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode)
521 // */
522 // public Integer countTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode) {
523 // return countTaxaByName(queryString, matchMode, selectMode, null);
524 // }
525
526 // /* (non-Javadoc)
527 // * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode, eu.etaxonomy.cdm.model.reference.ReferenceBase)
528 // */
529 // public Integer countTaxaByName(String queryString,
530 // MatchMode matchMode, SelectMode selectMode, ReferenceBase sec) {
531 //
532 // Long count = countTaxaByName(queryString, matchMode, selectMode, sec, null);
533 // return count.intValue();
534 //
535 // }
536
537 // public Integer countTaxaByName(String queryString, MatchMode matchMode, Boolean accepted) {
538 //
539 // SelectMode selectMode = (accepted ? SelectMode.TAXA : SelectMode.SYNONYMS);
540 // Long count = countTaxaByName(queryString, matchMode, selectMode, null, null);
541 // return count.intValue();
542 // }
543
544
545 public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {
546 return super.list(pagesize, page);
547 }
548
549 public List<Synonym> getAllSynonyms(Integer limit, Integer start) {
550 Criteria criteria = getSession().createCriteria(Synonym.class);
551
552 if(limit != null) {
553 criteria.setFirstResult(start);
554 criteria.setMaxResults(limit);
555 }
556
557 return criteria.list();
558 }
559
560 public List<Taxon> getAllTaxa(Integer limit, Integer start) {
561 Criteria criteria = getSession().createCriteria(Taxon.class);
562
563 if(limit != null) {
564 criteria.setFirstResult(start);
565 criteria.setMaxResults(limit);
566 }
567
568 return criteria.list();
569 }
570
571
572
573 public List<RelationshipBase> getAllRelationships(Integer limit, Integer start) {
574 AuditEvent auditEvent = getAuditEventFromContext();
575 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
576 Criteria criteria = getSession().createCriteria(RelationshipBase.class);
577 return (List<RelationshipBase>)criteria.list();
578 } else {
579 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase.class,auditEvent.getRevisionNumber());
580 return (List<RelationshipBase>)query.getResultList();
581 }
582 }
583
584 /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */
585 // private boolean nullifyTaxonomicParent(Taxon taxon) {
586 //
587 // try {
588 // Method nullifyTaxonomicParent = taxon.getClass().getMethod("nullifyTaxonomicParent");
589 // nullifyTaxonomicParent.invoke(taxon);
590 // } catch (NoSuchMethodException ex) {
591 // logger.error("NoSuchMethod: " + ex.getMessage());
592 // return false;
593 // } catch (IllegalArgumentException ex) {
594 // logger.error("IllegalArgumentException: " + ex.getMessage());
595 // return false;
596 // } catch (IllegalAccessException ex) {
597 // logger.error("IllegalAccessException: " + ex.getMessage());
598 // return false;
599 // } catch (InvocationTargetException ex) {
600 // logger.error("IllegalAccessException: " + ex.getMessage());
601 // return false;
602 // }
603 // return true;
604 // }
605
606 @Override
607 public UUID delete(TaxonBase taxonBase) throws DataAccessException{
608 if (taxonBase == null){
609 logger.warn("TaxonBase was 'null'");
610 return null;
611 }
612
613 // Merge the object in if it is detached
614 //
615 // I think this is preferable to catching lazy initialization errors
616 // as that solution only swallows and hides the exception, but doesn't
617 // actually solve it.
618 getSession().merge(taxonBase);
619
620 for(Iterator<Annotation> iterator = taxonBase.getAnnotations().iterator(); iterator.hasNext();) {
621 Annotation annotation = iterator.next();
622 annotation.setAnnotatedObj(null);
623 iterator.remove();
624 getSession().delete(annotation);
625 }
626
627 for(Iterator<Marker> iterator = taxonBase.getMarkers().iterator(); iterator.hasNext();) {
628 Marker marker = iterator.next();
629 marker.setMarkedObj(null);
630 iterator.remove();
631 getSession().delete(marker);
632 }
633
634 for(Iterator<Extension> iterator = taxonBase.getExtensions().iterator(); iterator.hasNext();) {
635 Extension extension = iterator.next();
636 extension.setExtendedObj(null);
637 iterator.remove();
638 getSession().delete(extension);
639 }
640
641 for(Iterator<IdentifiableSource> iterator = taxonBase.getSources().iterator(); iterator.hasNext();) {
642 IdentifiableSource source = iterator.next();
643 source.setSourcedObj(null);
644 iterator.remove();
645 getSession().delete(source);
646 }
647
648 for(Iterator<Rights> iterator = taxonBase.getRights().iterator(); iterator.hasNext();) {
649 Rights rights = iterator.next();
650 iterator.remove();
651 getSession().delete(rights);
652 }
653
654 if (taxonBase instanceof Taxon){ // is Taxon
655 //taxonRelationships
656 Taxon taxon = (Taxon)taxonBase;
657
658 for (Iterator<TaxonRelationship> iterator = taxon.getRelationsFromThisTaxon().iterator(); iterator.hasNext();){
659 TaxonRelationship relationFromThisTaxon = iterator.next();
660 iterator.remove();
661
662 // decrease children count of taxonomic parent by one
663 if (relationFromThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {
664 Taxon toTaxon = relationFromThisTaxon.getToTaxon(); // parent
665 if (toTaxon != null) {
666 toTaxon.setTaxonomicChildrenCount(toTaxon.getTaxonomicChildrenCount() - 1);
667 }
668 }
669 relationFromThisTaxon.setToTaxon(null);
670 relationFromThisTaxon.setFromTaxon(null);
671 getSession().delete(relationFromThisTaxon);
672 }
673
674 for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){
675 TaxonRelationship relationToThisTaxon = iterator.next();
676 iterator.remove();
677
678 // set parent cache of child to null
679 if (relationToThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {
680 Taxon fromTaxon = relationToThisTaxon.getFromTaxon(); // child
681 if (fromTaxon != null) {
682 fromTaxon.nullifyTaxonomicParent();
683 }
684 }
685 relationToThisTaxon.setFromTaxon(null);
686 relationToThisTaxon.setToTaxon(null);
687 getSession().delete(relationToThisTaxon);
688 }
689
690 //SynonymRelationships
691 for (Iterator<SynonymRelationship> iterator = taxon.getSynonymRelations().iterator(); iterator.hasNext();){
692 SynonymRelationship synonymRelation = iterator.next();
693 iterator.remove();
694 synonymRelation.setAcceptedTaxon(null);
695 synonymRelation.setSynonym(null);
696 getSession().delete(synonymRelation);
697 }
698
699 // Descriptions
700 for (Iterator<TaxonDescription> iterDesc = taxon.getDescriptions().iterator(); iterDesc.hasNext();) {
701 TaxonDescription taxonDescription = iterDesc.next();
702 iterDesc.remove();
703 //taxonDescription.setTaxon(null);
704 Field field = ReflectionUtils.findField(TaxonDescription.class, "taxon", Taxon.class);
705 ReflectionUtils.makeAccessible(field);
706 ReflectionUtils.setField(field, taxonDescription, null);
707 for (Iterator<DescriptionElementBase> iterDescElem =
708 taxonDescription.getElements().iterator(); iterDescElem.hasNext();) {
709 DescriptionElementBase descriptionElement = iterDescElem.next();
710 iterDescElem.remove();
711 getSession().delete(descriptionElement);
712 }
713 getSession().delete(taxonDescription);
714 }
715
716 taxon.nullifyTaxonomicParent();
717
718 } else { //is Synonym
719 Synonym synonym = (Synonym)taxonBase;
720 for (Iterator<SynonymRelationship> iterator = synonym.getSynonymRelations().iterator(); iterator.hasNext();){
721 SynonymRelationship synonymRelation = iterator.next();
722 iterator.remove();
723 synonymRelation.setAcceptedTaxon(null);
724 synonymRelation.setSynonym(null);
725 } ;
726 }
727 return super.delete(taxonBase);
728 }
729
730
731 // TODO add generic return type !!
732 public List findByName(String queryString, MatchMode matchMode, int page, int pagesize, boolean onlyAcccepted) {
733 ArrayList<Criterion> criteria = new ArrayList<Criterion>();
734 //TODO ... Restrictions.eq(propertyName, value)
735 return super.findByTitle(queryString, matchMode, page, pagesize, criteria);
736
737 }
738
739 public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted) {
740 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
741 Criteria crit = getSession().createCriteria(type);
742 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
743 crit.setProjection(Projections.rowCount());
744 int result = ((Integer)crit.list().get(0)).intValue();
745 return result;
746 }
747
748
749 public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted, List<Criterion> criteria) {
750 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
751 Criteria crit = getSession().createCriteria(type);
752 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
753 if(criteria != null){
754 for (Criterion criterion : criteria) {
755 crit.add(criterion);
756 }
757 }
758 crit.setProjection(Projections.rowCount());
759 int result = ((Integer)crit.list().get(0)).intValue();
760 return result;
761 }
762
763 public int countTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Direction direction) {
764 AuditEvent auditEvent = getAuditEventFromContext();
765 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
766 Query query = null;
767
768 if(type == null) {
769 query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction+" = :relatedTaxon");
770 } else {
771 query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction+" = :relatedTaxon and taxonRelationship.type = :type");
772 query.setParameter("type",type);
773 }
774 query.setParameter("relatedTaxon", taxon);
775
776 return ((Long)query.uniqueResult()).intValue();
777 } else {
778 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
779 query.add(AuditEntity.relatedId(direction.toString()).eq(taxon.getId()));
780 query.addProjection(AuditEntity.id().count("id"));
781
782 if(type != null) {
783 query.add(AuditEntity.relatedId("type").eq(type.getId()));
784 }
785
786 return ((Long)query.getSingleResult()).intValue();
787 }
788 }
789
790 public int countSynonyms(Taxon taxon, SynonymRelationshipType type) {
791 AuditEvent auditEvent = getAuditEventFromContext();
792 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
793 Query query = null;
794
795 if(type == null) {
796 query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo");
797 } else {
798 query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");
799 query.setParameter("type",type);
800 }
801
802 query.setParameter("relatedTo", taxon);
803
804 return ((Long)query.uniqueResult()).intValue();
805 } else {
806 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
807 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
808 query.addProjection(AuditEntity.id().count("id"));
809
810 if(type != null) {
811 query.add(AuditEntity.relatedId("type").eq(type.getId()));
812 }
813
814 return ((Long)query.getSingleResult()).intValue();
815 }
816 }
817
818 public int count(Class<? extends TaxonBase> clazz, String queryString) {
819 checkNotInPriorView("TaxonDaoHibernateImpl.count(String queryString, Boolean accepted)");
820 QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
821
822 try {
823 org.apache.lucene.search.Query query = queryParser.parse(queryString);
824
825 FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
826 org.hibernate.search.FullTextQuery fullTextQuery = null;
827
828 if(clazz == null) {
829 fullTextQuery = fullTextSession.createFullTextQuery(query, type);
830 } else {
831 fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
832 }
833
834 Integer result = fullTextQuery.getResultSize();
835 return result;
836
837 } catch (ParseException e) {
838 throw new QueryParseException(e, queryString);
839 }
840 }
841
842 // public int countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
843 //
844 // SelectMode selectMode = (accepted ? SelectMode.TAXA : SelectMode.SYNONYMS);
845 // Long count = countTaxaByName(queryString, MatchMode.ANYWHERE, selectMode , sec, null);
846 //
847 // return count.intValue();
848 // }
849
850 public int countTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank) {
851 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank)");
852 Criteria criteria = null;
853
854 if(clazz == null) {
855 criteria = getSession().createCriteria(TaxonBase.class);
856 } else {
857 criteria = getSession().createCriteria(clazz);
858 }
859
860 criteria.setFetchMode( "name", FetchMode.JOIN );
861 criteria.createAlias("name", "name");
862
863 if(genusOrUninomial != null) {
864 criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
865 }
866
867 if(infraGenericEpithet != null) {
868 criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
869 }
870
871 if(specificEpithet != null) {
872 criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
873 }
874
875 if(infraSpecificEpithet != null) {
876 criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
877 }
878
879 if(rank != null) {
880 criteria.add(Restrictions.eq("name.rank", rank));
881 }
882
883 criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
884
885 return (Integer)criteria.uniqueResult();
886 }
887
888 public List<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber) {
889 checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber)");
890 Criteria criteria = null;
891
892 if(clazz == null) {
893 criteria = getSession().createCriteria(TaxonBase.class);
894 } else {
895 criteria = getSession().createCriteria(clazz);
896 }
897
898 criteria.setFetchMode( "name", FetchMode.JOIN );
899 criteria.createAlias("name", "name");
900
901 if(genusOrUninomial == null) {
902 criteria.add(Restrictions.isNull("name.genusOrUninomial"));
903 } else if(!genusOrUninomial.equals("*")) {
904 criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
905 }
906
907 if(infraGenericEpithet == null) {
908 criteria.add(Restrictions.isNull("name.infraGenericEpithet"));
909 } else if(!infraGenericEpithet.equals("*")) {
910 criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
911 }
912
913 if(specificEpithet == null) {
914 criteria.add(Restrictions.isNull("name.specificEpithet"));
915 } else if(!specificEpithet.equals("*")) {
916 criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
917
918 }
919
920 if(infraSpecificEpithet == null) {
921 criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));
922 } else if(!infraSpecificEpithet.equals("*")) {
923 criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
924 }
925
926 if(rank != null) {
927 criteria.add(Restrictions.eq("name.rank", rank));
928 }
929
930 if(pageSize != null) {
931 criteria.setMaxResults(pageSize);
932 if(pageNumber != null) {
933 criteria.setFirstResult(pageNumber * pageSize);
934 } else {
935 criteria.setFirstResult(0);
936 }
937 }
938
939 return (List<TaxonBase>)criteria.list();
940 }
941
942 public List<TaxonRelationship> getTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths, Direction direction) {
943 AuditEvent auditEvent = getAuditEventFromContext();
944 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
945 Criteria criteria = getSession().createCriteria(TaxonRelationship.class);
946
947 criteria.add(Restrictions.eq("relatedTo", taxon));
948 if(type != null) {
949 criteria.add(Restrictions.eq("type", type));
950 }
951
952 addOrder(criteria,orderHints);
953
954 if(pageSize != null) {
955 criteria.setMaxResults(pageSize);
956 if(pageNumber != null) {
957 criteria.setFirstResult(pageNumber * pageSize);
958 } else {
959 criteria.setFirstResult(0);
960 }
961 }
962
963 List<TaxonRelationship> result = (List<TaxonRelationship>)criteria.list();
964 defaultBeanInitializer.initializeAll(result, propertyPaths);
965
966 return result;
967 } else {
968 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
969 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
970
971 if(type != null) {
972 query.add(AuditEntity.relatedId("type").eq(type.getId()));
973 }
974
975 if(pageSize != null) {
976 query.setMaxResults(pageSize);
977 if(pageNumber != null) {
978 query.setFirstResult(pageNumber * pageSize);
979 } else {
980 query.setFirstResult(0);
981 }
982 }
983
984 List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();
985 defaultBeanInitializer.initializeAll(result, propertyPaths);
986
987 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
988 // and we can't live without this functionality in CATE as it screws up the whole
989 // taxon tree thing
990 if(orderHints != null && !orderHints.isEmpty()) {
991 SortedSet<TaxonRelationship> sortedList = new TreeSet<TaxonRelationship>(new TaxonRelationshipFromTaxonComparator());
992 sortedList.addAll(result);
993 return new ArrayList<TaxonRelationship>(sortedList);
994 }
995
996 return result;
997 }
998 }
999
1000 class TaxonRelationshipFromTaxonComparator implements Comparator<TaxonRelationship> {
1001
1002 public int compare(TaxonRelationship o1, TaxonRelationship o2) {
1003 return o1.getFromTaxon().getTitleCache().compareTo(o2.getFromTaxon().getTitleCache());
1004 }
1005
1006 }
1007
1008 public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
1009 AuditEvent auditEvent = getAuditEventFromContext();
1010 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
1011 Criteria criteria = getSession().createCriteria(SynonymRelationship.class);
1012
1013 criteria.add(Restrictions.eq("relatedTo", taxon));
1014 if(type != null) {
1015 criteria.add(Restrictions.eq("type", type));
1016 }
1017
1018 addOrder(criteria,orderHints);
1019
1020 if(pageSize != null) {
1021 criteria.setMaxResults(pageSize);
1022 if(pageNumber != null) {
1023 criteria.setFirstResult(pageNumber * pageSize);
1024 } else {
1025 criteria.setFirstResult(0);
1026 }
1027 }
1028
1029 List<SynonymRelationship> result = (List<SynonymRelationship>)criteria.list();
1030 defaultBeanInitializer.initializeAll(result, propertyPaths);
1031
1032 return result;
1033 } else {
1034 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
1035 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
1036
1037 if(type != null) {
1038 query.add(AuditEntity.relatedId("type").eq(type.getId()));
1039 }
1040
1041 if(pageSize != null) {
1042 query.setMaxResults(pageSize);
1043 if(pageNumber != null) {
1044 query.setFirstResult(pageNumber * pageSize);
1045 } else {
1046 query.setFirstResult(0);
1047 }
1048 }
1049
1050 List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();
1051 defaultBeanInitializer.initializeAll(result, propertyPaths);
1052
1053 return result;
1054 }
1055 }
1056
1057 public List<TaxonBase> search(Class<? extends TaxonBase> clazz, String queryString,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
1058 checkNotInPriorView("TaxonDaoHibernateImpl.searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber)");
1059 QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
1060 List<TaxonBase> results = new ArrayList<TaxonBase>();
1061
1062 try {
1063 org.apache.lucene.search.Query query = queryParser.parse(queryString);
1064
1065 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
1066 org.hibernate.search.FullTextQuery fullTextQuery = null;
1067
1068 if(clazz == null) {
1069 fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);
1070 } else {
1071 fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
1072 }
1073
1074 addOrder(fullTextQuery,orderHints);
1075
1076 if(pageSize != null) {
1077 fullTextQuery.setMaxResults(pageSize);
1078 if(pageNumber != null) {
1079 fullTextQuery.setFirstResult(pageNumber * pageSize);
1080 } else {
1081 fullTextQuery.setFirstResult(0);
1082 }
1083 }
1084
1085 List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();
1086 defaultBeanInitializer.initializeAll(result, propertyPaths);
1087 return result;
1088
1089 } catch (ParseException e) {
1090 throw new QueryParseException(e, queryString);
1091 }
1092 }
1093
1094 public void purgeIndex() {
1095 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
1096 for(Class clazz : indexedClasses) {
1097 fullTextSession.purgeAll(clazz); // remove all taxon base from indexes
1098 }
1099 fullTextSession.flushToIndexes();
1100 }
1101
1102 public void rebuildIndex() {
1103 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
1104
1105 for(TaxonBase taxonBase : list(null,null)) { // re-index all taxon base
1106 Hibernate.initialize(taxonBase.getName());
1107 fullTextSession.index(taxonBase);
1108 }
1109 fullTextSession.flushToIndexes();
1110 }
1111
1112 public void optimizeIndex() {
1113 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
1114 SearchFactory searchFactory = fullTextSession.getSearchFactory();
1115 for(Class clazz : indexedClasses) {
1116 searchFactory.optimize(clazz); // optimize the indices ()
1117 }
1118 fullTextSession.flushToIndexes();
1119 }
1120
1121 public String suggestQuery(String queryString) {
1122 checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
1123 String alternativeQueryString = null;
1124 if (alternativeSpellingSuggestionParser != null) {
1125 try {
1126
1127 alternativeSpellingSuggestionParser.parse(queryString);
1128 org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser.suggest(queryString);
1129 if (alternativeQuery != null) {
1130 alternativeQueryString = alternativeQuery
1131 .toString("name.titleCache");
1132 }
1133
1134 } catch (ParseException e) {
1135 throw new QueryParseException(e, queryString);
1136 }
1137 }
1138 return alternativeQueryString;
1139 }
1140
1141 /*
1142 * (non-Javadoc)
1143 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.TaxonomicTree)
1144 */
1145 public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByTaxonomicTree(TaxonomicTree taxonomicTree) {
1146
1147 int taxonomicTreeId = taxonomicTree.getId();
1148
1149 String queryString = "SELECT nodes.uuid, taxa.titleCache FROM TaxonNode AS nodes LEFT JOIN TaxonBase AS taxa ON nodes.taxon_id = taxa.id WHERE taxa.DTYPE = 'Taxon' AND nodes.taxonomictree_id = " + taxonomicTreeId;
1150
1151 List<Object[]> result = getSession().createSQLQuery(queryString).list();
1152
1153 if(result.size() == 0){
1154 return null;
1155 }else{
1156 List<UuidAndTitleCache<TaxonNode>> list = new ArrayList<UuidAndTitleCache<TaxonNode>>(result.size());
1157
1158 for (Object object : result){
1159
1160 Object[] objectArray = (Object[]) object;
1161
1162 UUID uuid = UUID.fromString((String) objectArray[0]);
1163 String titleCache = (String) objectArray[1];
1164
1165 list.add(new UuidAndTitleCache(TaxonNode.class, uuid, titleCache));
1166 }
1167
1168 return list;
1169 }
1170 }
1171
1172
1173 public class UuidAndTitleCacheOfAcceptedTaxon{
1174 UUID uuid;
1175
1176 String titleCache;
1177
1178 public UuidAndTitleCacheOfAcceptedTaxon(UUID uuid, String titleCache){
1179 this.uuid = uuid;
1180 this.titleCache = titleCache;
1181 }
1182
1183 public UUID getUuid() {
1184 return uuid;
1185 }
1186
1187 public void setUuid(UUID uuid) {
1188 this.uuid = uuid;
1189 }
1190
1191 public String getTitleCache() {
1192 return titleCache;
1193 }
1194
1195 public void setTitleCache(String titleCache) {
1196 this.titleCache = titleCache;
1197 }
1198 }
1199
1200 @Override
1201 public TaxonBase find(LSID lsid) {
1202 TaxonBase taxonBase = super.find(lsid);
1203 if(taxonBase != null) {
1204 List<String> propertyPaths = new ArrayList<String>();
1205 propertyPaths.add("createdBy");
1206 propertyPaths.add("updatedBy");
1207 propertyPaths.add("name");
1208 propertyPaths.add("sec");
1209 propertyPaths.add("relationsToThisTaxon");
1210 propertyPaths.add("relationsToThisTaxon.fromTaxon");
1211 propertyPaths.add("relationsToThisTaxon.toTaxon");
1212 propertyPaths.add("relationsFromThisTaxon");
1213 propertyPaths.add("relationsFromThisTaxon.toTaxon");
1214 propertyPaths.add("relationsToThisTaxon.type");
1215 propertyPaths.add("synonymRelations");
1216 propertyPaths.add("synonymRelations.synonym");
1217 propertyPaths.add("synonymRelations.type");
1218 propertyPaths.add("descriptions");
1219
1220 defaultBeanInitializer.initialize(taxonBase, propertyPaths);
1221 }
1222 return taxonBase;
1223 }
1224 }