minor
[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.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Set;
20 import java.util.SortedSet;
21 import java.util.TreeSet;
22 import java.util.UUID;
23
24 import org.apache.log4j.Logger;
25 import org.apache.lucene.queryParser.ParseException;
26 import org.hibernate.Criteria;
27 import org.hibernate.FetchMode;
28 import org.hibernate.Hibernate;
29 import org.hibernate.Query;
30 import org.hibernate.Session;
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.springframework.beans.factory.annotation.Autowired;
39 import org.springframework.beans.factory.annotation.Qualifier;
40 import org.springframework.dao.DataAccessException;
41 import org.springframework.stereotype.Repository;
42
43 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
44 import eu.etaxonomy.cdm.model.common.CdmBase;
45 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
46 import eu.etaxonomy.cdm.model.common.LSID;
47 import eu.etaxonomy.cdm.model.common.OriginalSourceBase;
48 import eu.etaxonomy.cdm.model.common.RelationshipBase;
49 import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
50 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
51 import eu.etaxonomy.cdm.model.location.NamedArea;
52 import eu.etaxonomy.cdm.model.name.NonViralName;
53 import eu.etaxonomy.cdm.model.name.Rank;
54 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
55 import eu.etaxonomy.cdm.model.name.TaxonNameComparator;
56 import eu.etaxonomy.cdm.model.name.ZoologicalName;
57 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
58 import eu.etaxonomy.cdm.model.taxon.Synonym;
59 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
60 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
61 import eu.etaxonomy.cdm.model.taxon.Taxon;
62 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
63 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
64 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
65 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
66 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
67 import eu.etaxonomy.cdm.model.view.AuditEvent;
68 import eu.etaxonomy.cdm.persistence.dao.QueryParseException;
69 import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;
70 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
71 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
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 import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;
77
78
79 /**
80 * @author a.mueller
81 * @created 24.11.2008
82 * @version 1.0
83 */
84 @Repository
85 @Qualifier("taxonDaoHibernateImpl")
86 public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implements ITaxonDao {
87 private AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser;
88 private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);
89
90 public TaxonDaoHibernateImpl() {
91 super(TaxonBase.class);
92 indexedClasses = new Class[2];
93 indexedClasses[0] = Taxon.class;
94 indexedClasses[1] = Synonym.class;
95 super.defaultField = "name.titleCache_tokenized";
96 }
97
98 @Autowired
99 private ITaxonNameDao taxonNameDao;
100
101 @Autowired(required = false) //TODO switched of because it caused problems when starting CdmApplicationController
102 public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser) {
103 this.alternativeSpellingSuggestionParser = alternativeSpellingSuggestionParser;
104 }
105
106
107 /* (non-Javadoc)
108 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)
109 */
110 public List<Taxon> getRootTaxa(ReferenceBase sec) {
111 return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);
112 }
113
114 /* (non-Javadoc)
115 * @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)
116 */
117 public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications, List<String> propertyPaths) {
118 checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");
119 if (onlyWithChildren == null){
120 onlyWithChildren = true;
121 }
122 if (withMisapplications == null){
123 withMisapplications = true;
124 }
125 if (cdmFetch == null){
126 cdmFetch = CdmFetch.NO_FETCH();
127 }
128
129 Criteria crit = getSession().createCriteria(Taxon.class);
130
131 crit.setFetchMode("name", FetchMode.JOIN);
132 crit.createAlias("name", "name");
133
134 if (rank != null) {
135 crit.add(Restrictions.eq("name.rank", rank));
136 }else{
137 crit.add(Restrictions.isNull("taxonomicParentCache"));
138 }
139
140 if (sec != null){
141 crit.add(Restrictions.eq("sec", sec) );
142 }
143
144 if (! cdmFetch.includes(CdmFetch.FETCH_CHILDTAXA())){
145 logger.info("Not fetching child taxa");
146 //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)
147 crit.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode.LAZY);
148 }
149
150 List<Taxon> results = new ArrayList<Taxon>();
151 List<Taxon> taxa = crit.list();
152 for(Taxon taxon : taxa){
153
154
155 //childTaxa
156 //TODO create restriction instead
157 // (a) not using cache fields
158 /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());
159 if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){
160 if (withMisapplications == true || ! taxon.isMisappliedName()){
161 defaultBeanInitializer.initialize(taxon, propertyPaths);
162 results.add(taxon);
163 }
164 }*/
165 // (b) using cache fields
166 if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){
167 if (withMisapplications == true || ! taxon.isMisapplication()){
168 defaultBeanInitializer.initialize(taxon, propertyPaths);
169 results.add(taxon);
170 }
171 }
172 }
173 return results;
174 }
175
176 /* (non-Javadoc)
177 * @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)
178 */
179 public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {
180 return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications, null);
181 }
182
183 /*
184 * (non-Javadoc)
185 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.model.reference.ReferenceBase)
186 */
187 public List<TaxonBase> getTaxaByName(String queryString, ReferenceBase sec) {
188
189 return getTaxaByName(queryString, true, sec);
190 }
191
192 /*
193 * (non-Javadoc)
194 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, java.lang.Boolean, eu.etaxonomy.cdm.model.reference.ReferenceBase)
195 */
196 public List<TaxonBase> getTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
197 checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, ReferenceBase sec)");
198
199 Criteria criteria = null;
200 if (accepted == true) {
201 criteria = getSession().createCriteria(Taxon.class);
202 } else {
203 criteria = getSession().createCriteria(Synonym.class);
204 }
205
206 criteria.setFetchMode( "name", FetchMode.JOIN );
207 criteria.createAlias("name", "name");
208
209 if (sec != null && sec.getId() != 0) {
210 criteria.add(Restrictions.eq("sec", sec ) );
211 }
212
213 if (queryString != null) {
214 criteria.add(Restrictions.ilike("name.nameCache", queryString));
215 }
216
217 return (List<TaxonBase>)criteria.list();
218 }
219
220 public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, MatchMode matchMode,
221 Integer pageSize, Integer pageNumber) {
222
223 return getTaxaByName(clazz, queryString, null, matchMode, null, pageSize, pageNumber, null);
224 }
225
226 /*
227 * (non-Javadoc)
228 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, java.lang.Boolean, java.lang.Integer, java.lang.Integer)
229 */
230 public List<TaxonBase> getTaxaByName(String queryString, MatchMode matchMode,
231 Boolean accepted, Integer pageSize, Integer pageNumber) {
232
233 if (accepted == true) {
234 return getTaxaByName(Taxon.class, queryString, matchMode, pageSize, pageNumber);
235 } else {
236 return getTaxaByName(Synonym.class, queryString, matchMode, pageSize, pageNumber);
237 }
238 }
239
240 /*
241 * (non-Javadoc)
242 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.TaxonomicTree, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
243 */
244 public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, TaxonomicTree taxonomicTree,
245 MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize,
246 Integer pageNumber, List<String> propertyPaths) {
247
248 boolean doCount = false;
249 Query query = prepareTaxaByName(clazz, "nameCache", queryString, taxonomicTree, matchMode, namedAreas, pageSize, pageNumber, doCount);
250 if (query != null){
251 List<TaxonBase> results = query.list();
252 //results.addAll (prepareTaxaByCommonName(queryString, taxonomicTree, matchMode, namedAreas, pageSize, pageNumber, doCount).list());
253 defaultBeanInitializer.initializeAll(results, propertyPaths);
254 //TaxonComparatorSearch comp = new TaxonComparatorSearch();
255 //Collections.sort(results, comp);
256 return results;
257 }
258 return new ArrayList<TaxonBase>();
259
260 }
261
262 /*
263 * (non-Javadoc)
264 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByCommonName(java.lang.String, eu.etaxonomy.cdm.model.taxon.TaxonomicTree, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
265 */
266 public List<TaxonBase> getTaxaByCommonName(String queryString, TaxonomicTree taxonomicTree,
267 MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize,
268 Integer pageNumber, List<String> propertyPaths) {
269 boolean doCount = false;
270 Query query = prepareTaxaByCommonName(queryString, taxonomicTree, matchMode, namedAreas, pageSize, pageNumber, doCount);
271 if (query != null){
272 List<TaxonBase> results = query.list();
273 defaultBeanInitializer.initializeAll(results, propertyPaths);
274 return results;
275 }
276 return new ArrayList<TaxonBase>();
277
278 }
279
280
281 /**
282 * @param clazz
283 * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>
284 * @param queryString
285 * @param taxonomicTree TODO
286 * @param matchMode
287 * @param namedAreas
288 * @param pageSize
289 * @param pageNumber
290 * @param doCount
291 * @return
292 *
293 * FIXME implement taxontree restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}
294 */
295 private Query prepareTaxaByName(Class<? extends TaxonBase> clazz, String searchField, String queryString, TaxonomicTree taxonomicTree,
296 MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount) {
297
298 //TODO ? checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec)");
299
300 String hqlQueryString = matchMode.queryStringFrom(queryString);
301
302 String selectWhat = (doCount ? "count(t)": "t");
303
304 String hql = "";
305 Set<NamedArea> areasExpanded = new HashSet<NamedArea>();
306 if(namedAreas != null && namedAreas.size() > 0){
307 // expand areas and restrict by distribution area
308 List<NamedArea> childAreas;
309 Query areaQuery = getSession().createQuery("select childArea from NamedArea as childArea left join childArea.partOf as parentArea where parentArea = :area");
310 expandNamedAreas(namedAreas, areasExpanded, areaQuery);
311 }
312 boolean doAreaRestriction = areasExpanded.size() > 0;
313
314 Set<UUID> namedAreasUuids = new HashSet<UUID>();
315 for (NamedArea area:areasExpanded){
316 namedAreasUuids.add(area.getUuid());
317 }
318
319 String taxonSubselect = null;
320 String synonymSubselect = null;
321
322 if(taxonomicTree != null){
323
324 if(doAreaRestriction){
325
326 taxonSubselect = "select t.id from" +
327 " Distribution e" +
328 " join e.inDescription d" +
329 " join d.taxon t" +
330 " join t.name n " +
331 " join t.taxonNodes as tn "+
332 " where" +
333 " e.area.uuid in (:namedAreasUuids) AND" +
334 " tn.taxonomicTree = :taxonomicTree" +
335 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
336
337
338 synonymSubselect = "select s.id from" +
339 " Distribution e" +
340 " join e.inDescription d" +
341 " join d.taxon t" + // the taxa
342 " join t.taxonNodes as tn "+
343 " join t.synonymRelations sr" +
344 " join sr.relatedFrom s" + // the synonyms
345 " join s.name sn"+
346 " where" +
347 " e.area.uuid in (:namedAreasUuids) AND" +
348 " tn.taxonomicTree = :taxonomicTree" +
349 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
350
351 } else {
352
353 taxonSubselect = "select t.id from" +
354 " Taxon t" +
355 " join t.name n " +
356 " join t.taxonNodes as tn "+
357 " where" +
358 " tn.taxonomicTree = :taxonomicTree" +
359 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
360
361 synonymSubselect = "select s.id from" +
362 " Taxon t" + // the taxa
363 " join t.taxonNodes as tn "+
364 " join t.synonymRelations sr" +
365 " join sr.relatedFrom s" + // the synonyms
366 " join s.name sn"+
367 " where" +
368 " tn.taxonomicTree = :taxonomicTree" +
369 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
370 }
371 } else {
372
373 if(doAreaRestriction){
374
375 taxonSubselect = "select t.id from " +
376 " Distribution e" +
377 " join e.inDescription d" +
378 " join d.taxon t" +
379 " join t.name n "+
380 " where" +
381 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
382 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
383
384 synonymSubselect = "select s.id from" +
385 " Distribution e" +
386 " join e.inDescription d" +
387 " join d.taxon t" + // the taxa
388 " join t.synonymRelations sr" +
389 " join sr.relatedFrom s" + // the synonyms
390 " join s.name sn"+
391 " where" +
392 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
393 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
394
395 } else {
396
397 taxonSubselect = "select t.id from " +
398 " Taxon t" +
399 " join t.name n "+
400 " where" +
401 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
402
403 synonymSubselect = "select s.id from" +
404 " Taxon t" + // the taxa
405 " join t.synonymRelations sr" +
406 " join sr.relatedFrom s" + // the synonyms
407 " join s.name sn"+
408 " where" +
409 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
410 }
411
412
413 }
414
415
416
417 // TODO mysql needs optimization: see http://www.xaprb.com/blog/2006/04/30/how-to-optimize-subqueries-and-joins-in-mysql/#commen
418 Query subTaxon = null;
419 Query subSynonym = null;
420 if(clazz.equals(Taxon.class)){
421 // find Taxa
422 subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);
423 //subTaxon = getSession().createQuery(taxonSubselect);
424
425 if(doAreaRestriction){
426 subTaxon.setParameterList("namedAreasUuids", namedAreasUuids);
427 }
428 if(taxonomicTree != null){
429 subTaxon.setParameter("taxonomicTree", taxonomicTree);
430 }
431 } else if(clazz.equals(Synonym.class)){
432 // find synonyms
433 subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);
434
435 if(doAreaRestriction){
436 subSynonym.setParameterList("namedAreasUuids", namedAreasUuids);
437 }
438 if(taxonomicTree != null){
439 subSynonym.setParameter("taxonomicTree", taxonomicTree);
440 }
441 } else {
442 // find taxa and synonyms
443 subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);
444 subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);
445 if(doAreaRestriction){
446 subTaxon.setParameterList("namedAreasUuids", namedAreasUuids);
447 subSynonym.setParameterList("namedAreasUuids", namedAreasUuids);
448 }
449 if(taxonomicTree != null){
450 subTaxon.setParameter("taxonomicTree", taxonomicTree);
451 subSynonym.setParameter("taxonomicTree", taxonomicTree);
452 }
453 }
454
455 List<Integer> taxa = new ArrayList<Integer>();
456 List<Integer> synonyms = new ArrayList<Integer>();
457 if(clazz.equals(Taxon.class)){
458 taxa = subTaxon.list();
459
460 }else if (clazz.equals(Synonym.class)){
461 synonyms = subSynonym.list();
462 }else {
463 taxa = subTaxon.list();
464 synonyms = subSynonym.list();
465 }
466 if(clazz.equals(Taxon.class)){
467 if (taxa.size()>0){
468 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa)";
469 }else{
470 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
471 }
472 } else if(clazz.equals(Synonym.class) ){
473 if (synonyms.size()>0){
474 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";
475 }else{
476 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
477 }
478 } else {
479 if(synonyms.size()>0 && taxa.size()>0){
480 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";
481 }else if (synonyms.size()>0 ){
482 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";
483 } else if (taxa.size()>0 ){
484 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) ";
485 } else{
486 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
487 }
488 }
489
490 if (hql == "") return null;
491 if(!doCount){
492 //hql += " order by t.titleCache"; //" order by t.name.nameCache";
493 hql += " order by t.name.genusOrUninomial, case when t.name.specificEpithet like '\"%\"' then 1 else 0 end, t.name.specificEpithet, t.name.rank desc, t.name.nameCache";
494
495
496 }
497
498 Query query = getSession().createQuery(hql);
499
500
501 if(clazz.equals(Taxon.class) && taxa.size()>0){
502 //find taxa
503 query.setParameterList("taxa", taxa );
504 } else if(clazz.equals(Synonym.class) && synonyms.size()>0){
505 // find synonyms
506 query.setParameterList("synonyms", synonyms);
507
508
509 } else {
510 // find taxa and synonyms
511 if (taxa.size()>0){
512 query.setParameterList("taxa", taxa);
513 }
514 if (synonyms.size()>0){
515 query.setParameterList("synonyms",synonyms);
516 }
517 if (taxa.size()== 0 && synonyms.size() == 0){
518 return null;
519 }
520 }
521
522
523 if(pageSize != null && !doCount) {
524 query.setMaxResults(pageSize);
525 if(pageNumber != null) {
526 query.setFirstResult(pageNumber * pageSize);
527 }
528 }
529
530 return query;
531 }
532
533 private Query prepareTaxaByCommonName(String queryString, TaxonomicTree taxonomicTree,
534 MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount){
535
536 String hql= "from Taxon t " +
537 "join t.descriptions d "+
538 "join d.descriptionElements e " +
539 "join e.feature f " +
540 "where f.supportsCommonTaxonName = true and e.name "+matchMode.getMatchOperator()+" :queryString";//and ls.text like 'common%'";
541
542 Query query = getSession().createQuery(hql);
543
544 query.setParameter("queryString", queryString);
545
546 if(pageSize != null && !doCount) {
547 query.setMaxResults(pageSize);
548 if(pageNumber != null) {
549 query.setFirstResult(pageNumber * pageSize);
550 }
551 }
552 return query;
553 }
554
555 /* (non-Javadoc)
556 * @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)
557 */
558 public long countTaxaByName(Class<? extends TaxonBase> clazz, String queryString, TaxonomicTree taxonomicTree,
559 MatchMode matchMode, Set<NamedArea> namedAreas) {
560
561 boolean doCount = true;
562 Query query = prepareTaxaByName(clazz, "nameCache", queryString, taxonomicTree, matchMode, namedAreas, null, null, doCount);
563 if (query != null) {
564 return (Long)query.uniqueResult();
565 }
566 return 0;
567
568 }
569
570 /**
571 * @param namedAreas
572 * @param areasExpanded
573 * @param areaQuery
574 */
575 private void expandNamedAreas(Collection<NamedArea> namedAreas, Set<NamedArea> areasExpanded, Query areaQuery) {
576 List<NamedArea> childAreas;
577 for(NamedArea a : namedAreas){
578 areasExpanded.add(a);
579 areaQuery.setParameter("area", a);
580 childAreas = areaQuery.list();
581 if(childAreas.size() > 0){
582 areasExpanded.addAll(childAreas);
583 expandNamedAreas(childAreas, areasExpanded, areaQuery);
584 }
585 }
586 }
587
588 // /* (non-Javadoc)
589 // * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode)
590 // */
591 // public Integer countTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode) {
592 // return countTaxaByName(queryString, matchMode, selectMode, null);
593 // }
594
595 // /* (non-Javadoc)
596 // * @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)
597 // */
598 // public Integer countTaxaByName(String queryString,
599 // MatchMode matchMode, SelectMode selectMode, ReferenceBase sec) {
600 //
601 // Long count = countTaxaByName(queryString, matchMode, selectMode, sec, null);
602 // return count.intValue();
603 //
604 // }
605
606 // public Integer countTaxaByName(String queryString, MatchMode matchMode, Boolean accepted) {
607 //
608 // SelectMode selectMode = (accepted ? SelectMode.TAXA : SelectMode.SYNONYMS);
609 // Long count = countTaxaByName(queryString, matchMode, selectMode, null, null);
610 // return count.intValue();
611 // }
612
613 public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {
614 return super.list(pagesize, page);
615 }
616
617 /*
618 * (non-Javadoc)
619 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllSynonyms(java.lang.Integer, java.lang.Integer)
620 */
621 public List<Synonym> getAllSynonyms(Integer limit, Integer start) {
622 Criteria criteria = getSession().createCriteria(Synonym.class);
623
624 if(limit != null) {
625 criteria.setFirstResult(start);
626 criteria.setMaxResults(limit);
627 }
628
629 return criteria.list();
630 }
631
632 /*
633 * (non-Javadoc)
634 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllTaxa(java.lang.Integer, java.lang.Integer)
635 */
636 public List<Taxon> getAllTaxa(Integer limit, Integer start) {
637 Criteria criteria = getSession().createCriteria(Taxon.class);
638
639 if(limit != null) {
640 criteria.setFirstResult(start);
641 criteria.setMaxResults(limit);
642 }
643
644 return criteria.list();
645 }
646
647 /*
648 * (non-Javadoc)
649 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllRelationships(java.lang.Integer, java.lang.Integer)
650 */
651 public List<RelationshipBase> getAllRelationships(Integer limit, Integer start) {
652 AuditEvent auditEvent = getAuditEventFromContext();
653 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
654 Criteria criteria = getSession().createCriteria(RelationshipBase.class);
655 criteria.setFirstResult(start);
656 criteria.setMaxResults(limit);
657 return (List<RelationshipBase>)criteria.list();
658 } else {
659 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase.class,auditEvent.getRevisionNumber());
660 return (List<RelationshipBase>)query.getResultList();
661 }
662 }
663
664 /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */
665 // private boolean nullifyTaxonomicParent(Taxon taxon) {
666 //
667 // try {
668 // Method nullifyTaxonomicParent = taxon.getClass().getMethod("nullifyTaxonomicParent");
669 // nullifyTaxonomicParent.invoke(taxon);
670 // } catch (NoSuchMethodException ex) {
671 // logger.error("NoSuchMethod: " + ex.getMessage());
672 // return false;
673 // } catch (IllegalArgumentException ex) {
674 // logger.error("IllegalArgumentException: " + ex.getMessage());
675 // return false;
676 // } catch (IllegalAccessException ex) {
677 // logger.error("IllegalAccessException: " + ex.getMessage());
678 // return false;
679 // } catch (InvocationTargetException ex) {
680 // logger.error("IllegalAccessException: " + ex.getMessage());
681 // return false;
682 // }
683 // return true;
684 // }
685
686 @Override
687 public UUID delete(TaxonBase taxonBase) throws DataAccessException{
688 if (taxonBase == null){
689 logger.warn("TaxonBase was 'null'");
690 return null;
691 }
692
693 // Merge the object in if it is detached
694 //
695 // I think this is preferable to catching lazy initialization errors
696 // as that solution only swallows and hides the exception, but doesn't
697 // actually solve it.
698 getSession().merge(taxonBase);
699
700 if (taxonBase instanceof Taxon){ // is Taxon
701 for (Iterator<TaxonRelationship> iterator = ((Taxon)taxonBase).getRelationsFromThisTaxon().iterator(); iterator.hasNext();){
702 TaxonRelationship relationFromThisTaxon = iterator.next();
703
704 // decrease children count of taxonomic parent by one
705 if (relationFromThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {
706 Taxon toTaxon = relationFromThisTaxon.getToTaxon(); // parent
707 if (toTaxon != null) {
708 toTaxon.setTaxonomicChildrenCount(toTaxon.getTaxonomicChildrenCount() - 1);
709 }
710 }
711 }
712 }
713
714 return super.delete(taxonBase);
715 }
716
717
718 /* (non-Javadoc)
719 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, int, int, boolean)
720 */
721 public List<TaxonBase> findByNameTitleCache(Class<? extends TaxonBase>clazz, String queryString, TaxonomicTree taxonomicTree, MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageNumber, Integer pageSize, List<String> propertyPaths) {
722
723 boolean doCount = false;
724 Query query = prepareTaxaByName(clazz, "titleCache", queryString, taxonomicTree, matchMode, namedAreas, pageSize, pageNumber, doCount);
725 if (query != null){
726 List<TaxonBase> results = query.list();
727 defaultBeanInitializer.initializeAll(results, propertyPaths);
728 return results;
729 }
730 return new ArrayList<TaxonBase>();
731
732 }
733
734 /*
735 * (non-Javadoc)
736 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean)
737 */
738 public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted) {
739 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
740 Criteria crit = getSession().createCriteria(type);
741 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
742 crit.setProjection(Projections.rowCount());
743 int result = ((Integer)crit.list().get(0)).intValue();
744 return result;
745 }
746
747 /*
748 * (non-Javadoc)
749 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean, java.util.List)
750 */
751 public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted, List<Criterion> criteria) {
752 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
753 Criteria crit = getSession().createCriteria(type);
754 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
755 if(criteria != null){
756 for (Criterion criterion : criteria) {
757 crit.add(criterion);
758 }
759 }
760 crit.setProjection(Projections.rowCount());
761 int result = ((Integer)crit.list().get(0)).intValue();
762 return result;
763 }
764
765 /*
766 * (non-Javadoc)
767 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)
768 */
769 public int countTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Direction direction) {
770 AuditEvent auditEvent = getAuditEventFromContext();
771 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
772 Query query = null;
773
774 if(type == null) {
775 query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction+" = :relatedTaxon");
776 } else {
777 query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction+" = :relatedTaxon and taxonRelationship.type = :type");
778 query.setParameter("type",type);
779 }
780 query.setParameter("relatedTaxon", taxon);
781
782 return ((Long)query.uniqueResult()).intValue();
783 } else {
784 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
785 query.add(AuditEntity.relatedId(direction.toString()).eq(taxon.getId()));
786 query.addProjection(AuditEntity.id().count("id"));
787
788 if(type != null) {
789 query.add(AuditEntity.relatedId("type").eq(type.getId()));
790 }
791
792 return ((Long)query.getSingleResult()).intValue();
793 }
794 }
795
796 /*
797 * (non-Javadoc)
798 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
799 */
800 public int countSynonyms(Taxon taxon, SynonymRelationshipType type) {
801 AuditEvent auditEvent = getAuditEventFromContext();
802 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
803 Criteria criteria = getSession().createCriteria(SynonymRelationship.class);
804
805 criteria.add(Restrictions.eq("relatedTo", taxon));
806 if(type != null) {
807 criteria.add(Restrictions.eq("type", type));
808 }
809 criteria.setProjection(Projections.rowCount());
810 return (Integer)criteria.uniqueResult();
811 } else {
812 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
813 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
814 query.addProjection(AuditEntity.id().count("id"));
815
816 if(type != null) {
817 query.add(AuditEntity.relatedId("type").eq(type.getId()));
818 }
819
820 return ((Long)query.getSingleResult()).intValue();
821 }
822 }
823
824 /*
825 * (non-Javadoc)
826 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
827 */
828 public int countSynonyms(Synonym synonym, SynonymRelationshipType type) {
829 AuditEvent auditEvent = getAuditEventFromContext();
830 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
831 Criteria criteria = getSession().createCriteria(SynonymRelationship.class);
832
833 criteria.add(Restrictions.eq("relatedFrom", synonym));
834 if(type != null) {
835 criteria.add(Restrictions.eq("type", type));
836 }
837
838 criteria.setProjection(Projections.rowCount());
839 return (Integer)criteria.uniqueResult();
840 } else {
841 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
842 query.add(AuditEntity.relatedId("relatedFrom").eq(synonym.getId()));
843 query.addProjection(AuditEntity.id().count("id"));
844
845 if(type != null) {
846 query.add(AuditEntity.relatedId("type").eq(type.getId()));
847 }
848
849 return ((Long)query.getSingleResult()).intValue();
850 }
851 }
852
853 /*
854 * (non-Javadoc)
855 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank)
856 */
857 public int countTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank) {
858 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank)");
859 Criteria criteria = null;
860
861 if(clazz == null) {
862 criteria = getSession().createCriteria(TaxonBase.class);
863 } else {
864 criteria = getSession().createCriteria(clazz);
865 }
866
867 criteria.setFetchMode( "name", FetchMode.JOIN );
868 criteria.createAlias("name", "name");
869
870 if(genusOrUninomial == null) {
871 criteria.add(Restrictions.isNull("name.genusOrUninomial"));
872 } else if(!genusOrUninomial.equals("*")) {
873 criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
874 }
875
876 if(infraGenericEpithet == null) {
877 criteria.add(Restrictions.isNull("name.infraGenericEpithet"));
878 } else if(!infraGenericEpithet.equals("*")) {
879 criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
880 }
881
882 if(specificEpithet == null) {
883 criteria.add(Restrictions.isNull("name.specificEpithet"));
884 } else if(!specificEpithet.equals("*")) {
885 criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
886
887 }
888
889 if(infraSpecificEpithet == null) {
890 criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));
891 } else if(!infraSpecificEpithet.equals("*")) {
892 criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
893 }
894
895 if(rank != null) {
896 criteria.add(Restrictions.eq("name.rank", rank));
897 }
898
899 criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
900
901 return (Integer)criteria.uniqueResult();
902 }
903
904 /*
905 * (non-Javadoc)
906 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)
907 */
908 public List<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber) {
909 checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber)");
910 Criteria criteria = null;
911
912 if(clazz == null) {
913 criteria = getSession().createCriteria(TaxonBase.class);
914 } else {
915 criteria = getSession().createCriteria(clazz);
916 }
917
918 criteria.setFetchMode( "name", FetchMode.JOIN );
919 criteria.createAlias("name", "name");
920
921 if(genusOrUninomial == null) {
922 criteria.add(Restrictions.isNull("name.genusOrUninomial"));
923 } else if(!genusOrUninomial.equals("*")) {
924 criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
925 }
926
927 if(infraGenericEpithet == null) {
928 criteria.add(Restrictions.isNull("name.infraGenericEpithet"));
929 } else if(!infraGenericEpithet.equals("*")) {
930 criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
931 }
932
933 if(specificEpithet == null) {
934 criteria.add(Restrictions.isNull("name.specificEpithet"));
935 } else if(!specificEpithet.equals("*")) {
936 criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
937
938 }
939
940 if(infraSpecificEpithet == null) {
941 criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));
942 } else if(!infraSpecificEpithet.equals("*")) {
943 criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
944 }
945
946 if(rank != null) {
947 criteria.add(Restrictions.eq("name.rank", rank));
948 }
949
950 if(pageSize != null) {
951 criteria.setMaxResults(pageSize);
952 if(pageNumber != null) {
953 criteria.setFirstResult(pageNumber * pageSize);
954 } else {
955 criteria.setFirstResult(0);
956 }
957 }
958
959 return (List<TaxonBase>)criteria.list();
960 }
961
962 /*
963 * (non-Javadoc)
964 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)
965 */
966 public List<TaxonRelationship> getTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths, Direction direction) {
967 AuditEvent auditEvent = getAuditEventFromContext();
968 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
969 Criteria criteria = getSession().createCriteria(TaxonRelationship.class);
970
971 criteria.add(Restrictions.eq("relatedTo", taxon));
972 if(type != null) {
973 criteria.add(Restrictions.eq("type", type));
974 }
975
976 addOrder(criteria,orderHints);
977
978 if(pageSize != null) {
979 criteria.setMaxResults(pageSize);
980 if(pageNumber != null) {
981 criteria.setFirstResult(pageNumber * pageSize);
982 } else {
983 criteria.setFirstResult(0);
984 }
985 }
986
987 List<TaxonRelationship> result = (List<TaxonRelationship>)criteria.list();
988 defaultBeanInitializer.initializeAll(result, propertyPaths);
989
990 return result;
991 } else {
992 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
993 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
994
995 if(type != null) {
996 query.add(AuditEntity.relatedId("type").eq(type.getId()));
997 }
998
999 if(pageSize != null) {
1000 query.setMaxResults(pageSize);
1001 if(pageNumber != null) {
1002 query.setFirstResult(pageNumber * pageSize);
1003 } else {
1004 query.setFirstResult(0);
1005 }
1006 }
1007
1008 List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();
1009 defaultBeanInitializer.initializeAll(result, propertyPaths);
1010
1011 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
1012 // and we can't live without this functionality in CATE as it screws up the whole
1013 // taxon tree thing
1014 if(orderHints != null && !orderHints.isEmpty()) {
1015 SortedSet<TaxonRelationship> sortedList = new TreeSet<TaxonRelationship>(new TaxonRelationshipFromTaxonComparator());
1016 sortedList.addAll(result);
1017 return new ArrayList<TaxonRelationship>(sortedList);
1018 }
1019
1020 return result;
1021 }
1022 }
1023
1024 class TaxonRelationshipFromTaxonComparator implements Comparator<TaxonRelationship> {
1025
1026 public int compare(TaxonRelationship o1, TaxonRelationship o2) {
1027 return o1.getFromTaxon().getTitleCache().compareTo(o2.getFromTaxon().getTitleCache());
1028 }
1029
1030 }
1031
1032 class SynonymRelationshipFromTaxonComparator implements Comparator<SynonymRelationship> {
1033
1034 public int compare(SynonymRelationship o1, SynonymRelationship o2) {
1035 return o1.getSynonym().getTitleCache().compareTo(o2.getSynonym().getTitleCache());
1036 }
1037
1038 }
1039
1040 /*
1041 * (non-Javadoc)
1042 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
1043 */
1044 public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
1045 AuditEvent auditEvent = getAuditEventFromContext();
1046 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
1047 Criteria criteria = getSession().createCriteria(SynonymRelationship.class);
1048
1049 criteria.add(Restrictions.eq("relatedTo", taxon));
1050 if(type != null) {
1051 criteria.add(Restrictions.eq("type", type));
1052 }
1053
1054 addOrder(criteria,orderHints);
1055
1056 if(pageSize != null) {
1057 criteria.setMaxResults(pageSize);
1058 if(pageNumber != null) {
1059 criteria.setFirstResult(pageNumber * pageSize);
1060 } else {
1061 criteria.setFirstResult(0);
1062 }
1063 }
1064
1065 List<SynonymRelationship> result = (List<SynonymRelationship>)criteria.list();
1066 defaultBeanInitializer.initializeAll(result, propertyPaths);
1067
1068 return result;
1069 } else {
1070 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
1071 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
1072
1073 if(type != null) {
1074 query.add(AuditEntity.relatedId("type").eq(type.getId()));
1075 }
1076
1077 if(pageSize != null) {
1078 query.setMaxResults(pageSize);
1079 if(pageNumber != null) {
1080 query.setFirstResult(pageNumber * pageSize);
1081 } else {
1082 query.setFirstResult(0);
1083 }
1084 }
1085
1086 List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();
1087 defaultBeanInitializer.initializeAll(result, propertyPaths);
1088
1089 return result;
1090 }
1091 }
1092
1093 /*
1094 * (non-Javadoc)
1095 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
1096 */
1097 public List<SynonymRelationship> getSynonyms(Synonym synonym, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
1098 AuditEvent auditEvent = getAuditEventFromContext();
1099 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
1100 Criteria criteria = getSession().createCriteria(SynonymRelationship.class);
1101
1102 criteria.add(Restrictions.eq("relatedFrom", synonym));
1103 if(type != null) {
1104 criteria.add(Restrictions.eq("type", type));
1105 }
1106
1107 addOrder(criteria,orderHints);
1108
1109 if(pageSize != null) {
1110 criteria.setMaxResults(pageSize);
1111 if(pageNumber != null) {
1112 criteria.setFirstResult(pageNumber * pageSize);
1113 } else {
1114 criteria.setFirstResult(0);
1115 }
1116 }
1117
1118 List<SynonymRelationship> result = (List<SynonymRelationship>)criteria.list();
1119 defaultBeanInitializer.initializeAll(result, propertyPaths);
1120
1121 return result;
1122 } else {
1123 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
1124 query.add(AuditEntity.relatedId("relatedFrom").eq(synonym.getId()));
1125
1126 if(type != null) {
1127 query.add(AuditEntity.relatedId("type").eq(type.getId()));
1128 }
1129
1130 if(pageSize != null) {
1131 query.setMaxResults(pageSize);
1132 if(pageNumber != null) {
1133 query.setFirstResult(pageNumber * pageSize);
1134 } else {
1135 query.setFirstResult(0);
1136 }
1137 }
1138
1139 List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();
1140 defaultBeanInitializer.initializeAll(result, propertyPaths);
1141
1142 return result;
1143 }
1144 }
1145
1146 @Override
1147 public void rebuildIndex() {
1148 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
1149
1150 for(TaxonBase taxonBase : list(null,null)) { // re-index all taxon base
1151 Hibernate.initialize(taxonBase.getName());
1152 fullTextSession.index(taxonBase);
1153 }
1154 fullTextSession.flushToIndexes();
1155 }
1156
1157 @Override
1158 public String suggestQuery(String queryString) {
1159 checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
1160 String alternativeQueryString = null;
1161 if (alternativeSpellingSuggestionParser != null) {
1162 try {
1163
1164 alternativeSpellingSuggestionParser.parse(queryString);
1165 org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser.suggest(queryString);
1166 if (alternativeQuery != null) {
1167 alternativeQueryString = alternativeQuery
1168 .toString("name.titleCache");
1169 }
1170
1171 } catch (ParseException e) {
1172 throw new QueryParseException(e, queryString);
1173 }
1174 }
1175 return alternativeQueryString;
1176 }
1177
1178 /*
1179 * (non-Javadoc)
1180 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.TaxonomicTree)
1181 */
1182 public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByTaxonomicTree(TaxonomicTree taxonomicTree) {
1183
1184 int taxonomicTreeId = taxonomicTree.getId();
1185
1186 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;
1187
1188 List<Object[]> result = getSession().createSQLQuery(queryString).list();
1189
1190 if(result.size() == 0){
1191 return null;
1192 }else{
1193 List<UuidAndTitleCache<TaxonNode>> list = new ArrayList<UuidAndTitleCache<TaxonNode>>(result.size());
1194
1195 for (Object object : result){
1196
1197 Object[] objectArray = (Object[]) object;
1198
1199 UUID uuid = UUID.fromString((String) objectArray[0]);
1200 String titleCache = (String) objectArray[1];
1201
1202 list.add(new UuidAndTitleCache(TaxonNode.class, uuid, titleCache));
1203 }
1204
1205 return list;
1206 }
1207 }
1208
1209
1210 public class UuidAndTitleCacheOfAcceptedTaxon{
1211 UUID uuid;
1212
1213 String titleCache;
1214
1215 public UuidAndTitleCacheOfAcceptedTaxon(UUID uuid, String titleCache){
1216 this.uuid = uuid;
1217 this.titleCache = titleCache;
1218 }
1219
1220 public UUID getUuid() {
1221 return uuid;
1222 }
1223
1224 public void setUuid(UUID uuid) {
1225 this.uuid = uuid;
1226 }
1227
1228 public String getTitleCache() {
1229 return titleCache;
1230 }
1231
1232 public void setTitleCache(String titleCache) {
1233 this.titleCache = titleCache;
1234 }
1235 }
1236
1237 @Override
1238 public TaxonBase find(LSID lsid) {
1239 TaxonBase taxonBase = super.find(lsid);
1240 if(taxonBase != null) {
1241 List<String> propertyPaths = new ArrayList<String>();
1242 propertyPaths.add("createdBy");
1243 propertyPaths.add("updatedBy");
1244 propertyPaths.add("name");
1245 propertyPaths.add("sec");
1246 propertyPaths.add("relationsToThisTaxon");
1247 propertyPaths.add("relationsToThisTaxon.fromTaxon");
1248 propertyPaths.add("relationsToThisTaxon.toTaxon");
1249 propertyPaths.add("relationsFromThisTaxon");
1250 propertyPaths.add("relationsFromThisTaxon.toTaxon");
1251 propertyPaths.add("relationsToThisTaxon.type");
1252 propertyPaths.add("synonymRelations");
1253 propertyPaths.add("synonymRelations.synonym");
1254 propertyPaths.add("synonymRelations.type");
1255 propertyPaths.add("descriptions");
1256
1257 defaultBeanInitializer.initialize(taxonBase, propertyPaths);
1258 }
1259 return taxonBase;
1260 }
1261
1262 public List<TaxonBase> getTaxaByCommonName(String queryString,
1263 TaxonomicTree taxonomicTree, MatchMode matchMode,
1264 Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber) {
1265 // TODO Auto-generated method stub
1266 return null;
1267 }
1268
1269
1270 public List<Synonym> createAllInferredSynonyms(Taxon taxon, TaxonomicTree tree){
1271 List <Synonym> inferredSynonyms = new ArrayList<Synonym>();
1272
1273 inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.INFERRED_EPITHET_OF()));
1274 inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.INFERRED_GENUS_OF()));
1275 inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.POTENTIAL_COMBINATION_OF()));
1276
1277 return inferredSynonyms;
1278 }
1279
1280
1281 /**
1282 * Returns an existing ZoologicalName or extends an internal hashmap if it does not exist.
1283 * Very likely only useful for createInferredSynonyms().
1284 * @param uuid
1285 * @param zooHashMap
1286 * @return
1287 */
1288 private ZoologicalName getZoologicalName(UUID uuid, HashMap <UUID, ZoologicalName> zooHashMap) {
1289 ZoologicalName taxonName = this.taxonNameDao.findZoologicalNameByUUID(uuid);
1290 if (taxonName == null) {
1291 taxonName = zooHashMap.get(uuid);
1292 }
1293 return taxonName;
1294 }
1295
1296 public List<Synonym> createInferredSynonyms(Taxon taxon, TaxonomicTree tree, SynonymRelationshipType type){
1297 List <Synonym> inferredSynonyms = new ArrayList<Synonym>();
1298 List<Synonym> inferredSynonymsToBeRemoved = new ArrayList<Synonym>();
1299
1300 HashMap <UUID, ZoologicalName> zooHashMap = new HashMap<UUID, ZoologicalName>();
1301 UUID uuid;
1302
1303 uuid= taxon.getName().getUuid();
1304 ZoologicalName taxonName = getZoologicalName(uuid, zooHashMap);
1305 String epithetOfTaxon = taxonName.getSpecificEpithet();
1306 String genusOfTaxon = taxonName.getGenusOrUninomial();
1307 Set<TaxonNode> nodes = taxon.getTaxonNodes();
1308 List<String> taxonNames = new ArrayList<String>();
1309
1310 for (TaxonNode node: nodes){
1311 HashMap<String, String> synonymsGenus = new HashMap<String, String>(); // Changed this to be able to store the idInSource to a genusName
1312 List<String> synonymsEpithet = new ArrayList<String>();
1313
1314 if (node.getTaxonomicTree().equals(tree)){
1315 if (!node.isTopmostNode()){
1316 TaxonNode parent = (TaxonNode)node.getParent();
1317 parent = (TaxonNode)HibernateProxyHelper.deproxy(parent);
1318 TaxonNameBase parentName = parent.getTaxon().getName();
1319 parentName = (TaxonNameBase)HibernateProxyHelper.deproxy(parentName);
1320
1321 //create inferred synonyms for species, subspecies or subgenus
1322 if (parentName.isGenus() || parentName.isSpecies() || parentName.getRank().equals(Rank.SUBGENUS())){
1323
1324 Synonym inferredEpithet;
1325 Synonym inferredGenus = null;
1326 Synonym potentialCombination;
1327
1328 List<String> propertyPaths = new ArrayList<String>();
1329 propertyPaths.add("synonym");
1330 propertyPaths.add("synonym.name");
1331 List<OrderHint> orderHints = new ArrayList<OrderHint>();
1332 orderHints.add(new OrderHint("relatedFrom.titleCache", SortOrder.ASCENDING));
1333
1334 List<SynonymRelationship> synonymRelationshipsOfGenus = getSynonyms(parent.getTaxon(), SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints,propertyPaths);
1335 List<SynonymRelationship> synonymRelationshipsOfTaxon= getSynonyms(taxon, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints,propertyPaths);
1336
1337 if (type.equals(SynonymRelationshipType.INFERRED_EPITHET_OF())){
1338
1339 for (SynonymRelationship synonymRelationOfGenus:synonymRelationshipsOfGenus){
1340 TaxonNameBase synName;
1341 ZoologicalName inferredSynName;
1342 Synonym syn = synonymRelationOfGenus.getSynonym();
1343 HibernateProxyHelper.deproxy(syn);
1344
1345 // Determine the idInSource
1346 String idInSource = getIdInSource(syn);
1347
1348 // Determine the sourceReference
1349 ReferenceBase sourceReference = syn.getSec();
1350
1351 synName = syn.getName();
1352 ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);
1353 String synGenusName = zooName.getGenusOrUninomial();
1354 if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){
1355 synonymsGenus.put(synGenusName, idInSource);
1356 }
1357 inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());
1358
1359 // DEBUG
1360 if (epithetOfTaxon == null) {
1361 logger.error("This specificEpithet is NULL");
1362 }
1363
1364 inferredSynName.setSpecificEpithet(epithetOfTaxon);
1365 inferredSynName.setGenusOrUninomial(synGenusName);
1366 inferredEpithet = Synonym.NewInstance(inferredSynName, null);
1367
1368 // Set the sourceReference
1369 inferredEpithet.setSec(sourceReference);
1370
1371 // Add the original source
1372 if (idInSource != null) {
1373 IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "InferredEpithetOf", syn.getSec(), null);
1374
1375 // Add the citation
1376 ReferenceBase citation = getCitation(syn);
1377 if (citation != null) {
1378 originalSource.setCitation(citation);
1379 inferredEpithet.addSource(originalSource);
1380 }
1381 }
1382
1383 taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());
1384 inferredSynonyms.add(inferredEpithet);
1385 inferredSynName.generateTitle();
1386 zooHashMap.put(inferredSynName.getUuid(), inferredSynName);
1387 taxonNames.add(inferredSynName.getNameCache());
1388 }
1389
1390 if (!taxonNames.isEmpty()){
1391 List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);
1392 ZoologicalName name;
1393 if (!synNotInCDM.isEmpty()){
1394 inferredSynonymsToBeRemoved.clear();
1395
1396 for (Synonym syn :inferredSynonyms){
1397 name = getZoologicalName(syn.getName().getUuid(), zooHashMap);
1398 if (!synNotInCDM.contains(name.getNameCache())){
1399 inferredSynonymsToBeRemoved.add(syn);
1400 }
1401 }
1402
1403 // Remove identified Synonyms from inferredSynonyms
1404 for (Synonym synonym : inferredSynonymsToBeRemoved) {
1405 inferredSynonyms.remove(synonym);
1406 }
1407 }
1408 }
1409
1410 }else if (type.equals(SynonymRelationshipType.INFERRED_GENUS_OF())){
1411
1412
1413 for (SynonymRelationship synonymRelationOfTaxon:synonymRelationshipsOfTaxon){
1414 TaxonNameBase synName;
1415 ZoologicalName inferredSynName;
1416
1417 Synonym syn = synonymRelationOfTaxon.getSynonym();
1418 synName =syn.getName();
1419 HibernateProxyHelper.deproxy(syn);
1420
1421 // Determine the idInSource
1422 String idInSource = getIdInSource(syn);
1423
1424 // Determine the sourceReference
1425 ReferenceBase sourceReference = syn.getSec();
1426
1427 synName = syn.getName();
1428 ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);
1429 String speciesEpithetName = zooName.getSpecificEpithet();
1430 if (synonymsEpithet != null && !synonymsEpithet.contains(speciesEpithetName)){
1431 synonymsEpithet.add(speciesEpithetName);
1432 }
1433 inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());
1434 inferredSynName.setSpecificEpithet(speciesEpithetName);
1435 inferredSynName.setGenusOrUninomial(genusOfTaxon);
1436 inferredGenus = Synonym.NewInstance(inferredSynName, null);
1437
1438 // Set the sourceReference
1439 inferredGenus.setSec(sourceReference);
1440
1441 // Add the original source
1442 if (idInSource != null) {
1443 IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "InferredGenusOf", syn.getSec(), null);
1444
1445 // Add the citation
1446 ReferenceBase citation = getCitation(syn);
1447 if (citation != null) {
1448 originalSource.setCitation(citation);
1449 inferredGenus.addSource(originalSource);
1450 }
1451 }
1452
1453 taxon.addSynonym(inferredGenus, SynonymRelationshipType.INFERRED_EPITHET_OF());
1454 inferredSynonyms.add(inferredGenus);
1455 inferredSynName.generateTitle();
1456 zooHashMap.put(inferredSynName.getUuid(), inferredSynName);
1457 taxonNames.add(inferredSynName.getNameCache());
1458 }
1459
1460 if (!taxonNames.isEmpty()){
1461 List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);
1462 ZoologicalName name;
1463 if (!synNotInCDM.isEmpty()){
1464 inferredSynonymsToBeRemoved.clear();
1465
1466 for (Synonym syn :inferredSynonyms){
1467 name = getZoologicalName(syn.getName().getUuid(), zooHashMap);
1468 if (!synNotInCDM.contains(name.getNameCache())){
1469 inferredSynonymsToBeRemoved.add(syn);
1470 }
1471 }
1472
1473 // Remove identified Synonyms from inferredSynonyms
1474 for (Synonym synonym : inferredSynonymsToBeRemoved) {
1475 inferredSynonyms.remove(synonym);
1476 }
1477 }
1478 }
1479
1480 }else if (type.equals(SynonymRelationshipType.POTENTIAL_COMBINATION_OF())){
1481
1482 ReferenceBase sourceReference = null; // TODO: Determination of sourceReference is redundant
1483
1484 for (SynonymRelationship synonymRelationOfGenus:synonymRelationshipsOfGenus){
1485 TaxonNameBase synName;
1486 Synonym syn = synonymRelationOfGenus.getSynonym();
1487 synName =syn.getName();
1488
1489 HibernateProxyHelper.deproxy(syn);
1490
1491 // Set the sourceReference
1492 sourceReference = syn.getSec();
1493
1494 // Determine the idInSource
1495 String idInSource = getIdInSource(syn);
1496
1497 ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);
1498 String synGenusName = zooName.getGenusOrUninomial();
1499 if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){
1500 synonymsGenus.put(synGenusName, idInSource);
1501 }
1502 }
1503
1504 ZoologicalName inferredSynName;
1505 for (SynonymRelationship synonymRelationOfTaxon:synonymRelationshipsOfTaxon){
1506
1507 Synonym syn = synonymRelationOfTaxon.getSynonym();
1508 HibernateProxyHelper.deproxy(syn);
1509
1510 // Set sourceReference
1511 sourceReference = syn.getSec();
1512
1513 ZoologicalName zooName = getZoologicalName(syn.getName().getUuid(), zooHashMap);
1514 String epithetName = zooName.getSpecificEpithet();
1515 if (epithetName != null && !synonymsEpithet.contains(epithetName)){
1516 synonymsEpithet.add(epithetName);
1517 }
1518 }
1519 for (String epithetName:synonymsEpithet){
1520 for (String genusName: synonymsGenus.keySet()){
1521 inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());
1522 inferredSynName.setSpecificEpithet(epithetName);
1523 inferredSynName.setGenusOrUninomial(genusName);
1524 potentialCombination = Synonym.NewInstance(inferredSynName, null);
1525
1526 // Set the sourceReference
1527 potentialCombination.setSec(sourceReference);
1528
1529 // Add the original source
1530 String idInSource = synonymsGenus.get(genusName);
1531 if (idInSource != null) {
1532 IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "PotentialCombinationOf", sourceReference, null);
1533
1534 // Add the citation
1535 if (sourceReference != null) {
1536 originalSource.setCitation(sourceReference);
1537 potentialCombination.addSource(originalSource);
1538 }
1539 }
1540
1541 inferredSynonyms.add(potentialCombination);
1542 inferredSynName.generateTitle();
1543 zooHashMap.put(inferredSynName.getUuid(), inferredSynName);
1544 taxonNames.add(inferredSynName.getNameCache());
1545 }
1546
1547 if (!taxonNames.isEmpty()){
1548 List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);
1549 ZoologicalName name;
1550 if (!synNotInCDM.isEmpty()){
1551 inferredSynonymsToBeRemoved.clear();
1552
1553 for (Synonym syn :inferredSynonyms){
1554 try{
1555 name = (ZoologicalName) syn.getName();
1556 }catch (ClassCastException e){
1557 name = getZoologicalName(syn.getName().getUuid(), zooHashMap);
1558 }
1559 if (!synNotInCDM.contains(name.getNameCache())){
1560 inferredSynonymsToBeRemoved.add(syn);
1561 }
1562 }
1563
1564 // Remove identified Synonyms from inferredSynonyms
1565 for (Synonym synonym : inferredSynonymsToBeRemoved) {
1566 inferredSynonyms.remove(synonym);
1567 }
1568 }
1569 }
1570 }
1571 }else {
1572 logger.info("The synonymrelationship type is not defined.");
1573 return null;
1574 }
1575 }
1576 }
1577 }
1578 }
1579
1580
1581 return inferredSynonyms;
1582 }
1583
1584
1585 /**
1586 * Returns the idInSource for a given Synonym.
1587 * @param syn
1588 */
1589 private String getIdInSource(Synonym syn) {
1590 String idInSource = null;
1591 Set<IdentifiableSource> sources = syn.getSources();
1592 if (sources.size() == 1) {
1593 IdentifiableSource source = sources.iterator().next();
1594 if (source != null) {
1595 idInSource = source.getIdInSource();
1596 }
1597 } else if (sources.size() > 1) {
1598 int count = 1;
1599 idInSource = "";
1600 for (IdentifiableSource source : sources) {
1601 idInSource += source.getIdInSource();
1602 if (count < sources.size()) {
1603 idInSource += "; ";
1604 }
1605 count++;
1606 }
1607 }
1608
1609 return idInSource;
1610 }
1611
1612 /**
1613 * Returns the citation for a given Synonym.
1614 * @param syn
1615 */
1616 private ReferenceBase getCitation(Synonym syn) {
1617 ReferenceBase citation = null;
1618 Set<IdentifiableSource> sources = syn.getSources();
1619 if (sources.size() == 1) {
1620 IdentifiableSource source = sources.iterator().next();
1621 if (source != null) {
1622 citation = source.getCitation();
1623 }
1624 } else if (sources.size() > 1) {
1625 logger.warn("This Synonym has more than one source: " + syn.getUuid() + " (" + syn.getTitleCache() +")");
1626 }
1627
1628 return citation;
1629 }
1630
1631 /* private void xxx(List<SynonymRelationship> synonymRelationships, HashMap <UUID, ZoologicalName> zooHashMap, SynonymRelationshipType type, String addString){
1632
1633 for (SynonymRelationship synonymRelation:synonymRelationships){
1634 TaxonNameBase synName;
1635 NonViralName inferredSynName;
1636 Synonym syn = synonymRelation.getSynonym();
1637 HibernateProxyHelper.deproxy(syn);
1638
1639 synName = syn.getName();
1640 ZoologicalName zooName = zooHashMap.get(synName.getUuid());
1641 String synGenusName = zooName.getGenusOrUninomial();
1642
1643 switch(type.getId()){
1644 case SynonymRelationshipType.INFERRED_EPITHET_OF().getId():
1645 inferredSynName.setSpecificEpithet(addString);
1646 break;
1647 case SynonymRelationshipType.INFERRED_GENUS_OF().getId():
1648 break;
1649 case SynonymRelationshipType.POTENTIAL_COMBINATION_OF().getId():
1650 break;
1651 default:
1652 }
1653 if (!synonymsGenus.contains(synGenusName)){
1654 synonymsGenus.add(synGenusName);
1655 }
1656 inferredSynName = NonViralName.NewInstance(Rank.SPECIES());
1657 inferredSynName.setSpecificEpithet(epithetOfTaxon);
1658 inferredSynName.setGenusOrUninomial(synGenusName);
1659 inferredEpithet = Synonym.NewInstance(inferredSynName, null);
1660 taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());
1661 inferredSynonyms.add(inferredEpithet);
1662 inferredSynName.generateTitle();
1663 taxonNames.add(inferredSynName.getNameCache());
1664 }
1665
1666
1667 if (!taxonNames.isEmpty()){
1668 List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);
1669 ZoologicalName name;
1670 if (!synNotInCDM.isEmpty()){
1671 for (Synonym syn :inferredSynonyms){
1672 name =zooHashMap.get(syn.getName().getUuid());
1673 if (!synNotInCDM.contains(name.getNameCache())){
1674 inferredSynonyms.remove(syn);
1675 }
1676 }
1677 }
1678 }
1679 }*/
1680
1681 /*
1682 * (non-Javadoc)
1683 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countAllRelationships()
1684 */
1685 public int countAllRelationships() {
1686 List<RelationshipBase> relationships = this.getAllRelationships(null, 0);
1687 return relationships.size();
1688 }
1689
1690
1691 public List<String> taxaByNameNotInDB(List<String> taxonNames){
1692 List<TaxonBase> notInDB = new ArrayList<TaxonBase>();
1693 //get all taxa, already in db
1694 Query query = getSession().createQuery("from TaxonNameBase t where t.nameCache IN (:taxonList)");
1695 query.setParameterList("taxonList", taxonNames);
1696 List<TaxonNameBase> taxaInDB = query.list();
1697 //compare the original list with the result of the query
1698 for (TaxonNameBase taxonName: taxaInDB){
1699 if (taxonName.isInstanceOf(NonViralName.class)) {
1700 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1701 String nameCache = nonViralName.getNameCache();
1702 if (taxonNames.contains(nameCache)){
1703 taxonNames.remove(nameCache);
1704 }
1705 }
1706 }
1707
1708 return taxonNames;
1709 }
1710
1711 //TODO: mal nur mit UUID probieren (ohne fetch all properties), vielleicht geht das schneller?
1712 public List<UUID> findIdenticalTaxonNameIds(List<String> propertyPaths){
1713 Query query=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
1714 System.err.println("query: " + query.getQueryString());
1715 List<UUID> zooNames = query.list();
1716 System.err.println("number of identical names"+zooNames.size());
1717
1718
1719 return zooNames;
1720
1721 }
1722
1723 public List<TaxonNameBase> findIdenticalTaxonNames(List<String> propertyPaths) {
1724
1725 //hole alle TaxonNames, die es mindestens zweimal gibt.
1726
1727
1728
1729 Query query=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
1730 System.err.println("query: " + query.getQueryString());
1731 List<TaxonNameBase> zooNames = query.list();
1732 System.err.println("number of identical names"+zooNames.size());
1733
1734 TaxonNameComparator taxComp = new TaxonNameComparator();
1735 Collections.sort(zooNames, taxComp);
1736 System.err.println("list is sorted");
1737 for (TaxonNameBase taxonNameBase: zooNames){
1738 defaultBeanInitializer.initialize(taxonNameBase, propertyPaths);
1739 }
1740
1741 return zooNames;
1742 }
1743
1744 public List<TaxonNameBase> findIdenticalNamesNew(List<String> propertyPaths){
1745
1746 //Hole die beiden Source_ids von "Fauna Europaea" und "Erms" und in sources der names darf jeweils nur das entgegengesetzte auftreten (i member of tmb.taxonBases)
1747 Query query = getSession().createQuery("Select id from ReferenceBase where titleCache like 'Fauna Europaea database'");
1748 List<String> secRefFauna = query.list();
1749 query = getSession().createQuery("Select id from ReferenceBase where titleCache like 'ERMS'");
1750 List<String> secRefErms = query.list();
1751 //Query query = getSession().createQuery("select tmb2.nameCache from ZoologicalName tmb, TaxonBase tb1, ZoologicalName tmb2, TaxonBase tb2 where tmb.id != tmb2.id and tb1.name = tmb and tb2.name = tmb2 and tmb.nameCache = tmb2.nameCache and tb1.sec != tb2.sec");
1752 //Get all names of fauna europaea
1753 query = getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefFauna");
1754 query.setParameter("secRefFauna", secRefFauna.get(0));
1755 List<String> namesFauna= query.list();
1756
1757 //Get all names of erms
1758
1759 query = getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefErms");
1760 query.setParameter("secRefErms", secRefErms.get(0));
1761
1762 List<String> namesErms = query.list();
1763 /*TaxonNameComparator comp = new TaxonNameComparator();
1764 Collections.sort(namesFauna);
1765 Collections.sort(namesErms);
1766 */
1767 List <String> identicalNames = new ArrayList<String>();
1768 String predecessor = "";
1769
1770 for (String nameFauna: namesFauna){
1771 if (namesErms.contains(nameFauna)){
1772 identicalNames.add(nameFauna);
1773 }
1774 }
1775 System.err.println("number of identical names: " + identicalNames.size());
1776
1777 query = getSession().createQuery("from ZoologicalName zn where zn.nameCache IN (:identicalNames)");
1778 query.setParameterList("identicalNames", identicalNames);
1779 List<TaxonNameBase> result = query.list();
1780 TaxonNameBase temp = result.get(0);
1781
1782 Iterator<OriginalSourceBase> sources = temp.getSources().iterator();
1783 System.err.println(temp.getSources().size());
1784 if (sources.hasNext()){
1785 System.err.println("funktioniert..."+ sources.next().getIdInSource());
1786 //sources.next().getIdInSource();
1787 }
1788 TaxonNameComparator taxComp = new TaxonNameComparator();
1789 Collections.sort(result, taxComp);
1790 defaultBeanInitializer.initializeAll(result, propertyPaths);
1791 return result;
1792
1793 }
1794
1795
1796
1797 public String getPhylumName(TaxonNameBase name){
1798 List results = new ArrayList();
1799 try{
1800 Query query = getSession().createSQLQuery("select getPhylum("+ name.getId()+");");
1801 results = query.list();
1802 }catch(Exception e){
1803 System.err.println(name.getUuid());
1804 return null;
1805 }
1806 System.err.println("phylum of "+ name.getTitleCache() );
1807 return (String)results.get(0);
1808 }
1809
1810
1811 public long countTaxaByCommonName(String searchString,
1812 TaxonomicTree taxonomicTree, MatchMode matchMode,
1813 Set<NamedArea> namedAreas) {
1814 boolean doCount = true;
1815 Query query = prepareTaxaByCommonName(searchString, taxonomicTree, matchMode, namedAreas, null, null, doCount);
1816 if (query != null && !query.list().isEmpty()) {
1817 Object o = query.uniqueResult();
1818 if(o != null) {
1819 return (Long)o;
1820 }
1821 }
1822 return 0;
1823
1824 }
1825
1826
1827 public long deleteSynonymRelationships(Synonym syn) {
1828
1829 /*
1830 * DELETE RT
1831 FROM RelTaxon AS RT INNER JOIN
1832 Taxon AS FaEuSyn ON RT.TaxonFk1 = FaEuSyn.TaxonId INNER JOIN
1833 Taxon AS ERMSAcc ON FaEuSyn.RankFk = ERMSAcc.RankFk AND FaEuSyn.FullName = ERMSAcc.FullName AND ISNULL(FaEuSyn.TaxonStatusFk, 0)
1834 <> ERMSAcc.TaxonStatusFk
1835 WHERE (FaEuSyn.OriginalDB = N'FaEu') AND (ERMSAcc.OriginalDB = N'ERMS') AND (ERMSAcc.TaxonStatusFk = 1) AND (ERMSAcc.KingdomFk = 2) AND
1836 (RT.RelTaxonQualifierFk > 100)
1837 */
1838 Session session = this.getSession();
1839 Query q = session.createQuery("delete SynonymRelationship sr where sr.relatedFrom = :syn");
1840 q.setParameter("syn", syn);
1841 return q.executeUpdate();
1842 }
1843
1844
1845 @Override
1846 public Integer countSynonymRelationships(TaxonBase taxonBase,
1847 SynonymRelationshipType type, Direction relatedfrom) {
1848 AuditEvent auditEvent = getAuditEventFromContext();
1849 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
1850 Query query = null;
1851
1852 if(type == null) {
1853 query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom+" = :relatedSynonym");
1854 } else {
1855 query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom+" = :relatedSynonym and synonymRelationship.type = :type");
1856 query.setParameter("type",type);
1857 }
1858 query.setParameter("relatedTaxon", taxonBase);
1859
1860 return ((Long)query.uniqueResult()).intValue();
1861 } else {
1862 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
1863 query.add(AuditEntity.relatedId(relatedfrom.toString()).eq(taxonBase.getId()));
1864 query.addProjection(AuditEntity.id().count("id"));
1865
1866 if(type != null) {
1867 query.add(AuditEntity.relatedId("type").eq(type.getId()));
1868 }
1869
1870 return ((Long)query.getSingleResult()).intValue();
1871 }
1872 }
1873
1874
1875 @Override
1876 public List<SynonymRelationship> getSynonymRelationships(TaxonBase taxonBase,
1877 SynonymRelationshipType type, Integer pageSize, Integer pageNumber,
1878 List<OrderHint> orderHints, List<String> propertyPaths,
1879 Direction direction) {
1880
1881 AuditEvent auditEvent = getAuditEventFromContext();
1882 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
1883 Criteria criteria = getSession().createCriteria(SynonymRelationship.class);
1884
1885 if (direction.equals(Direction.relatedTo)){
1886 criteria.add(Restrictions.eq("relatedTo", taxonBase));
1887 }else{
1888 criteria.add(Restrictions.eq("relatedFrom", taxonBase));
1889 }
1890 if(type != null) {
1891 criteria.add(Restrictions.eq("type", type));
1892 }
1893
1894 addOrder(criteria,orderHints);
1895
1896 if(pageSize != null) {
1897 criteria.setMaxResults(pageSize);
1898 if(pageNumber != null) {
1899 criteria.setFirstResult(pageNumber * pageSize);
1900 } else {
1901 criteria.setFirstResult(0);
1902 }
1903 }
1904
1905 List<SynonymRelationship> result = (List<SynonymRelationship>)criteria.list();
1906 defaultBeanInitializer.initializeAll(result, propertyPaths);
1907
1908 return result;
1909 } else {
1910 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
1911
1912 if (direction.equals(Direction.relatedTo)){
1913 query.add(AuditEntity.relatedId("relatedTo").eq(taxonBase.getId()));
1914 }else{
1915 query.add(AuditEntity.relatedId("relatedFrom").eq(taxonBase.getId()));
1916 }
1917
1918 if(type != null) {
1919 query.add(AuditEntity.relatedId("type").eq(type.getId()));
1920 }
1921
1922 if(pageSize != null) {
1923 query.setMaxResults(pageSize);
1924 if(pageNumber != null) {
1925 query.setFirstResult(pageNumber * pageSize);
1926 } else {
1927 query.setFirstResult(0);
1928 }
1929 }
1930
1931 List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();
1932 defaultBeanInitializer.initializeAll(result, propertyPaths);
1933
1934 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
1935 // and we can't live without this functionality in CATE as it screws up the whole
1936 // taxon tree thing
1937 if(orderHints != null && !orderHints.isEmpty()) {
1938 SortedSet<SynonymRelationship> sortedList = new TreeSet<SynonymRelationship>(new SynonymRelationshipFromTaxonComparator());
1939 sortedList.addAll(result);
1940 return new ArrayList<SynonymRelationship>(sortedList);
1941 }
1942
1943 return result;
1944 }
1945 }
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956 }