2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.taxon
;
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
;
20 import java
.util
.SortedSet
;
21 import java
.util
.TreeSet
;
22 import java
.util
.UUID
;
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
;
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
.RelationshipBase
.Direction
;
50 import eu
.etaxonomy
.cdm
.model
.common
.UuidAndTitleCache
;
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
.Reference
;
58 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
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
.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
.model
.common
.IdentifiableEntity
;
74 import eu
.etaxonomy
.cdm
.persistence
.fetch
.CdmFetch
;
75 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
76 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
77 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
.SortOrder
;
86 @Qualifier("taxonDaoHibernateImpl")
87 public class TaxonDaoHibernateImpl
extends IdentifiableDaoBase
<TaxonBase
> implements ITaxonDao
{
88 private AlternativeSpellingSuggestionParser
<TaxonBase
> alternativeSpellingSuggestionParser
;
89 private static final Logger logger
= Logger
.getLogger(TaxonDaoHibernateImpl
.class);
91 public TaxonDaoHibernateImpl() {
92 super(TaxonBase
.class);
93 indexedClasses
= new Class
[2];
94 indexedClasses
[0] = Taxon
.class;
95 indexedClasses
[1] = Synonym
.class;
96 super.defaultField
= "name.titleCache_tokenized";
100 private ITaxonNameDao taxonNameDao
;
102 @Autowired(required
= false) //TODO switched of because it caused problems when starting CdmApplicationController
103 public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser
<TaxonBase
> alternativeSpellingSuggestionParser
) {
104 this.alternativeSpellingSuggestionParser
= alternativeSpellingSuggestionParser
;
109 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference)
111 public List
<Taxon
> getRootTaxa(Reference sec
) {
112 return getRootTaxa(sec
, CdmFetch
.FETCH_CHILDTAXA(), true, false);
116 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)
118 public List
<Taxon
> getRootTaxa(Rank rank
, Reference sec
, CdmFetch cdmFetch
, Boolean onlyWithChildren
, Boolean withMisapplications
, List
<String
> propertyPaths
) {
119 checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");
120 if (onlyWithChildren
== null){
121 onlyWithChildren
= true;
123 if (withMisapplications
== null){
124 withMisapplications
= true;
126 if (cdmFetch
== null){
127 cdmFetch
= CdmFetch
.NO_FETCH();
130 Criteria crit
= getSession().createCriteria(Taxon
.class);
132 crit
.setFetchMode("name", FetchMode
.JOIN
);
133 crit
.createAlias("name", "name");
136 crit
.add(Restrictions
.eq("name.rank", rank
));
138 crit
.add(Restrictions
.isNull("taxonomicParentCache"));
142 crit
.add(Restrictions
.eq("sec", sec
) );
145 if (! cdmFetch
.includes(CdmFetch
.FETCH_CHILDTAXA())){
146 logger
.info("Not fetching child taxa");
147 //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)
148 crit
.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode
.LAZY
);
151 List
<Taxon
> results
= new ArrayList
<Taxon
>();
152 List
<Taxon
> taxa
= crit
.list();
153 for(Taxon taxon
: taxa
){
157 //TODO create restriction instead
158 // (a) not using cache fields
159 /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());
160 if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){
161 if (withMisapplications == true || ! taxon.isMisappliedName()){
162 defaultBeanInitializer.initialize(taxon, propertyPaths);
166 // (b) using cache fields
167 if (onlyWithChildren
== false || taxon
.hasTaxonomicChildren()){
168 if (withMisapplications
== true || ! taxon
.isMisapplication()){
169 defaultBeanInitializer
.initialize(taxon
, propertyPaths
);
178 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)
180 public List
<Taxon
> getRootTaxa(Reference sec
, CdmFetch cdmFetch
, Boolean onlyWithChildren
, Boolean withMisapplications
) {
181 return getRootTaxa(null, sec
, cdmFetch
, onlyWithChildren
, withMisapplications
, null);
186 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.model.reference.Reference)
188 public List
<TaxonBase
> getTaxaByName(String queryString
, Reference sec
) {
190 return getTaxaByName(queryString
, true, sec
);
195 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, java.lang.Boolean, eu.etaxonomy.cdm.model.reference.Reference)
197 public List
<TaxonBase
> getTaxaByName(String queryString
, Boolean accepted
, Reference sec
) {
198 checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, Reference sec)");
200 Criteria criteria
= null;
201 if (accepted
== true) {
202 criteria
= getSession().createCriteria(Taxon
.class);
204 criteria
= getSession().createCriteria(Synonym
.class);
207 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
208 criteria
.createAlias("name", "name");
210 if (sec
!= null && sec
.getId() != 0) {
211 criteria
.add(Restrictions
.eq("sec", sec
) );
214 if (queryString
!= null) {
215 criteria
.add(Restrictions
.ilike("name.nameCache", queryString
));
218 return (List
<TaxonBase
>)criteria
.list();
221 public List
<TaxonBase
> getTaxaByName(Class
<?
extends TaxonBase
> clazz
, String queryString
, MatchMode matchMode
,
222 Integer pageSize
, Integer pageNumber
) {
224 return getTaxaByName(clazz
, queryString
, null, matchMode
, null, pageSize
, pageNumber
, null);
229 * @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)
231 public List
<TaxonBase
> getTaxaByName(String queryString
, MatchMode matchMode
,
232 Boolean accepted
, Integer pageSize
, Integer pageNumber
) {
234 if (accepted
== true) {
235 return getTaxaByName(Taxon
.class, queryString
, matchMode
, pageSize
, pageNumber
);
237 return getTaxaByName(Synonym
.class, queryString
, matchMode
, pageSize
, pageNumber
);
243 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
245 public List
<TaxonBase
> getTaxaByName(Class
<?
extends TaxonBase
> clazz
, String queryString
, Classification classification
,
246 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
,
247 Integer pageNumber
, List
<String
> propertyPaths
) {
249 boolean doCount
= false;
251 Query query
= prepareTaxaByName(clazz
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
254 List
<TaxonBase
> results
= query
.list();
256 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
257 //TaxonComparatorSearch comp = new TaxonComparatorSearch();
258 //Collections.sort(results, comp);
262 return new ArrayList
<TaxonBase
>();
268 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
270 //new search for the editor, for performance issues the return values are only uuid and titleCache, to avoid the initialisation of all objects
271 @SuppressWarnings("unchecked")
272 public List
<UuidAndTitleCache
<TaxonBase
>> getTaxaByNameForEditor(Class
<?
extends TaxonBase
> clazz
, String queryString
, Classification classification
,
273 MatchMode matchMode
, Set
<NamedArea
> namedAreas
) {
277 boolean doCount
= false;
278 Query query
= prepareTaxaByNameForEditor(clazz
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, doCount
);
282 List
<Object
[]> results
= query
.list();
284 List
<UuidAndTitleCache
<TaxonBase
>> resultObjects
= new ArrayList
<UuidAndTitleCache
<TaxonBase
>>();
286 for(int i
= 0; i
<results
.size();i
++){
287 result
= results
.get(i
);
289 //unterscheiden von taxa und synonymen
290 if (clazz
.equals(Taxon
.class)){
291 resultObjects
.add( new UuidAndTitleCache(Taxon
.class, (UUID
) result
[0], (String
)result
[1]));
292 }else if (clazz
.equals(Synonym
.class)){
293 resultObjects
.add( new UuidAndTitleCache(Synonym
.class, (UUID
) result
[0], (String
)result
[1]));
295 if (result
[2].equals("synonym")) {
296 resultObjects
.add( new UuidAndTitleCache(Synonym
.class, (UUID
) result
[0], (String
)result
[1]));
299 resultObjects
.add( new UuidAndTitleCache(Taxon
.class, (UUID
) result
[0], (String
)result
[1]));
304 return resultObjects
;
307 return new ArrayList
<UuidAndTitleCache
<TaxonBase
>>();
313 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByCommonName(java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
315 public List
<TaxonBase
> getTaxaByCommonName(String queryString
, Classification classification
,
316 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
,
317 Integer pageNumber
, List
<String
> propertyPaths
) {
318 boolean doCount
= false;
319 Query query
= prepareTaxaByCommonName(queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
321 List
<TaxonBase
> results
= query
.list();
322 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
325 return new ArrayList
<TaxonBase
>();
331 * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>
333 * @param classification TODO
343 private Query
prepareTaxaByNameForEditor(Class
<?
extends TaxonBase
> clazz
, String searchField
, String queryString
, Classification classification
,
344 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, boolean doCount
) {
345 return prepareQuery(clazz
, searchField
, queryString
, classification
,
346 matchMode
, namedAreas
, doCount
, true);
349 private Query
prepareQuery(Class
<?
extends TaxonBase
> clazz
, String searchField
, String queryString
, Classification classification
,
350 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, boolean doCount
, boolean doForEditor
){
352 String hqlQueryString
= matchMode
.queryStringFrom(queryString
);
355 selectWhat
= "t.uuid, t.titleCache ";
356 }else selectWhat
= (doCount ?
"count(t)": "t");
359 Set
<NamedArea
> areasExpanded
= new HashSet
<NamedArea
>();
360 if(namedAreas
!= null && namedAreas
.size() > 0){
361 // expand areas and restrict by distribution area
362 List
<NamedArea
> childAreas
;
363 Query areaQuery
= getSession().createQuery("select childArea from NamedArea as childArea left join childArea.partOf as parentArea where parentArea = :area");
364 expandNamedAreas(namedAreas
, areasExpanded
, areaQuery
);
366 boolean doAreaRestriction
= areasExpanded
.size() > 0;
368 Set
<UUID
> namedAreasUuids
= new HashSet
<UUID
>();
369 for (NamedArea area
:areasExpanded
){
370 namedAreasUuids
.add(area
.getUuid());
373 String taxonSubselect
= null;
374 String synonymSubselect
= null;
376 if(classification
!= null){
378 if(doAreaRestriction
){
380 taxonSubselect
= "select t.id from" +
382 " join e.inDescription d" +
385 " join t.taxonNodes as tn "+
387 " e.area.uuid in (:namedAreasUuids) AND" +
388 " tn.classification = :classification" +
389 " AND n." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
392 synonymSubselect
= "select s.id from" +
394 " join e.inDescription d" +
395 " join d.taxon t" + // the taxa
396 " join t.taxonNodes as tn "+
397 " join t.synonymRelations sr" +
398 " join sr.relatedFrom s" + // the synonyms
401 " e.area.uuid in (:namedAreasUuids) AND" +
402 " tn.classification = :classification" +
403 " AND sn." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
407 taxonSubselect
= "select t.id from" +
410 " join t.taxonNodes as tn "+
412 " tn.classification = :classification" +
413 " AND n." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
415 synonymSubselect
= "select s.id from" +
416 " Taxon t" + // the taxa
417 " join t.taxonNodes as tn "+
418 " join t.synonymRelations sr" +
419 " join sr.relatedFrom s" + // the synonyms
422 " tn.classification = :classification" +
423 " AND sn." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
427 if(doAreaRestriction
){
429 taxonSubselect
= "select t.id from " +
431 " join e.inDescription d" +
435 (doAreaRestriction ?
" e.area.uuid in (:namedAreasUuids) AND" : "") +
436 " n." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
438 synonymSubselect
= "select s.id from" +
440 " join e.inDescription d" +
441 " join d.taxon t" + // the taxa
442 " join t.synonymRelations sr" +
443 " join sr.relatedFrom s" + // the synonyms
446 (doAreaRestriction ?
" e.area.uuid in (:namedAreasUuids) AND" : "") +
447 " sn." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
451 taxonSubselect
= "select t.id from " +
455 " n." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
457 synonymSubselect
= "select s.id from" +
458 " Taxon t" + // the taxa
459 " join t.synonymRelations sr" +
460 " join sr.relatedFrom s" + // the synonyms
463 " sn." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
472 Query subTaxon
= null;
473 Query subSynonym
= null;
474 if(clazz
.equals(Taxon
.class)){
476 subTaxon
= getSession().createQuery(taxonSubselect
).setParameter("queryString", hqlQueryString
);
477 //subTaxon = getSession().createQuery(taxonSubselect);
479 if(doAreaRestriction
){
480 subTaxon
.setParameterList("namedAreasUuids", namedAreasUuids
);
482 if(classification
!= null){
483 subTaxon
.setParameter("classification", classification
);
485 } else if(clazz
.equals(Synonym
.class)){
487 subSynonym
= getSession().createQuery(synonymSubselect
).setParameter("queryString", hqlQueryString
);
489 if(doAreaRestriction
){
490 subSynonym
.setParameterList("namedAreasUuids", namedAreasUuids
);
492 if(classification
!= null){
493 subSynonym
.setParameter("classification", classification
);
496 // find taxa and synonyms
497 subSynonym
= getSession().createQuery(synonymSubselect
).setParameter("queryString", hqlQueryString
);
498 subTaxon
= getSession().createQuery(taxonSubselect
).setParameter("queryString", hqlQueryString
);
499 if(doAreaRestriction
){
500 subTaxon
.setParameterList("namedAreasUuids", namedAreasUuids
);
501 subSynonym
.setParameterList("namedAreasUuids", namedAreasUuids
);
503 if(classification
!= null){
504 subTaxon
.setParameter("classification", classification
);
505 subSynonym
.setParameter("classification", classification
);
509 List
<Integer
> taxa
= new ArrayList
<Integer
>();
510 List
<Integer
> synonyms
= new ArrayList
<Integer
>();
511 if(clazz
.equals(Taxon
.class)){
512 taxa
= subTaxon
.list();
514 }else if (clazz
.equals(Synonym
.class)){
515 synonyms
= subSynonym
.list();
517 taxa
= subTaxon
.list();
518 synonyms
= subSynonym
.list();
520 if(clazz
.equals(Taxon
.class)){
522 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t" + " where t.id in (:taxa)";
524 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t";
526 } else if(clazz
.equals(Synonym
.class) ){
527 if (synonyms
.size()>0){
528 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t" + " where t.id in (:synonyms)";
530 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t";
533 if(synonyms
.size()>0 && taxa
.size()>0){
534 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";
535 hql
= "select " + selectWhat
+ ", case when t.id in (:taxa) then 'taxon' else 'synonym' end" + " from " + clazz
.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";
536 }else if (synonyms
.size()>0 ){
537 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t" + " where t.id in (:synonyms)";
538 } else if (taxa
.size()>0 ){
539 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t" + " where t.id in (:taxa) ";
541 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t";
545 if (hql
== "") return null;
547 //hql += " order by t.titleCache"; //" order by t.name.nameCache";
548 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";
553 Query query
= getSession().createQuery(hql
);
556 if(clazz
.equals(Taxon
.class) && taxa
.size()>0){
558 query
.setParameterList("taxa", taxa
);
559 } else if(clazz
.equals(Synonym
.class) && synonyms
.size()>0){
561 query
.setParameterList("synonyms", synonyms
);
565 // find taxa and synonyms
567 query
.setParameterList("taxa", taxa
);
569 if (synonyms
.size()>0){
570 query
.setParameterList("synonyms",synonyms
);
572 if (taxa
.size()== 0 && synonyms
.size() == 0){
583 * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>
585 * @param classification TODO
593 * FIXME implement classification restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}
595 private Query
prepareTaxaByName(Class
<?
extends TaxonBase
> clazz
, String searchField
, String queryString
, Classification classification
,
596 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
, boolean doCount
) {
598 //TODO ? checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, Reference sec)");
600 /*String hqlQueryString = matchMode.queryStringFrom(queryString);
602 String selectWhat = (doCount ? "count(t)": "t");
605 Set<NamedArea> areasExpanded = new HashSet<NamedArea>();
606 if(namedAreas != null && namedAreas.size() > 0){
607 // expand areas and restrict by distribution area
608 List<NamedArea> childAreas;
609 Query areaQuery = getSession().createQuery("select childArea from NamedArea as childArea left join childArea.partOf as parentArea where parentArea = :area");
610 expandNamedAreas(namedAreas, areasExpanded, areaQuery);
612 boolean doAreaRestriction = areasExpanded.size() > 0;
614 Set<UUID> namedAreasUuids = new HashSet<UUID>();
615 for (NamedArea area:areasExpanded){
616 namedAreasUuids.add(area.getUuid());
619 String taxonSubselect = null;
620 String synonymSubselect = null;
622 if(classification != null){
624 if(doAreaRestriction){
626 taxonSubselect = "select t.id from" +
628 " join e.inDescription d" +
631 " join t.taxonNodes as tn "+
633 " e.area.uuid in (:namedAreasUuids) AND" +
634 " tn.classification = :classification" +
635 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
638 synonymSubselect = "select s.id from" +
640 " join e.inDescription d" +
641 " join d.taxon t" + // the taxa
642 " join t.taxonNodes as tn "+
643 " join t.synonymRelations sr" +
644 " join sr.relatedFrom s" + // the synonyms
647 " e.area.uuid in (:namedAreasUuids) AND" +
648 " tn.classification = :classification" +
649 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
653 taxonSubselect = "select t.id from" +
656 " join t.taxonNodes as tn "+
658 " tn.classification = :classification" +
659 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
661 synonymSubselect = "select s.id from" +
662 " Taxon t" + // the taxa
663 " join t.taxonNodes as tn "+
664 " join t.synonymRelations sr" +
665 " join sr.relatedFrom s" + // the synonyms
668 " tn.classification = :classification" +
669 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
673 if(doAreaRestriction){
675 taxonSubselect = "select t.id from " +
677 " join e.inDescription d" +
681 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
682 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
684 synonymSubselect = "select s.id from" +
686 " join e.inDescription d" +
687 " join d.taxon t" + // the taxa
688 " join t.synonymRelations sr" +
689 " join sr.relatedFrom s" + // the synonyms
692 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
693 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
697 taxonSubselect = "select t.id from " +
701 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
703 synonymSubselect = "select s.id from" +
704 " Taxon t" + // the taxa
705 " join t.synonymRelations sr" +
706 " join sr.relatedFrom s" + // the synonyms
709 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
718 Query subTaxon = null;
719 Query subSynonym = null;
720 if(clazz.equals(Taxon.class)){
722 subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);
723 //subTaxon = getSession().createQuery(taxonSubselect);
725 if(doAreaRestriction){
726 subTaxon.setParameterList("namedAreasUuids", namedAreasUuids);
728 if(classification != null){
729 subTaxon.setParameter("classification", classification);
731 } else if(clazz.equals(Synonym.class)){
733 subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);
735 if(doAreaRestriction){
736 subSynonym.setParameterList("namedAreasUuids", namedAreasUuids);
738 if(classification != null){
739 subSynonym.setParameter("classification", classification);
742 // find taxa and synonyms
743 subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);
744 subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);
745 if(doAreaRestriction){
746 subTaxon.setParameterList("namedAreasUuids", namedAreasUuids);
747 subSynonym.setParameterList("namedAreasUuids", namedAreasUuids);
749 if(classification != null){
750 subTaxon.setParameter("classification", classification);
751 subSynonym.setParameter("classification", classification);
755 List<Integer> taxa = new ArrayList<Integer>();
756 List<Integer> synonyms = new ArrayList<Integer>();
757 if(clazz.equals(Taxon.class)){
758 taxa = subTaxon.list();
760 }else if (clazz.equals(Synonym.class)){
761 synonyms = subSynonym.list();
763 taxa = subTaxon.list();
764 synonyms = subSynonym.list();
766 if(clazz.equals(Taxon.class)){
768 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa)";
770 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
772 } else if(clazz.equals(Synonym.class) ){
773 if (synonyms.size()>0){
774 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";
776 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
779 if(synonyms.size()>0 && taxa.size()>0){
780 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";
781 }else if (synonyms.size()>0 ){
782 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";
783 } else if (taxa.size()>0 ){
784 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) ";
786 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
790 if (hql == "") return null;
792 //hql += " order by t.titleCache"; //" order by t.name.nameCache";
793 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";
798 Query query = getSession().createQuery(hql);
801 if(clazz.equals(Taxon.class) && taxa.size()>0){
803 query.setParameterList("taxa", taxa );
804 } else if(clazz.equals(Synonym.class) && synonyms.size()>0){
806 query.setParameterList("synonyms", synonyms);
810 // find taxa and synonyms
812 query.setParameterList("taxa", taxa);
814 if (synonyms.size()>0){
815 query.setParameterList("synonyms",synonyms);
817 if (taxa.size()== 0 && synonyms.size() == 0){
821 Query query
= prepareQuery(clazz
, searchField
, queryString
, classification
,
822 matchMode
, namedAreas
, doCount
, false);
824 if(pageSize
!= null && !doCount
) {
825 query
.setMaxResults(pageSize
);
826 if(pageNumber
!= null) {
827 query
.setFirstResult(pageNumber
* pageSize
);
834 private Query
prepareTaxaByCommonName(String queryString
, Classification classification
,
835 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
, boolean doCount
){
837 String hql
= "from Taxon t " +
838 "join t.descriptions d "+
839 "join d.descriptionElements e " +
840 "join e.feature f " +
841 "where f.supportsCommonTaxonName = true and e.name "+matchMode
.getMatchOperator()+" :queryString";//and ls.text like 'common%'";
843 Query query
= getSession().createQuery(hql
);
845 query
.setParameter("queryString", queryString
);
847 if(pageSize
!= null && !doCount
) {
848 query
.setMaxResults(pageSize
);
849 if(pageNumber
!= null) {
850 query
.setFirstResult(pageNumber
* pageSize
);
857 * @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.Reference, java.util.Set)
859 public long countTaxaByName(Class
<?
extends TaxonBase
> clazz
, String queryString
, Classification classification
,
860 MatchMode matchMode
, Set
<NamedArea
> namedAreas
) {
862 boolean doCount
= true;
863 Query query
= prepareTaxaByName(clazz
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, null, null, doCount
);
865 return (Long
)query
.uniqueResult();
873 * @param areasExpanded
876 private void expandNamedAreas(Collection
<NamedArea
> namedAreas
, Set
<NamedArea
> areasExpanded
, Query areaQuery
) {
877 List
<NamedArea
> childAreas
;
878 for(NamedArea a
: namedAreas
){
879 areasExpanded
.add(a
);
880 areaQuery
.setParameter("area", a
);
881 childAreas
= areaQuery
.list();
882 if(childAreas
.size() > 0){
883 areasExpanded
.addAll(childAreas
);
884 expandNamedAreas(childAreas
, areasExpanded
, areaQuery
);
890 // * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode)
892 // public Integer countTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode) {
893 // return countTaxaByName(queryString, matchMode, selectMode, null);
897 // * @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.Reference)
899 // public Integer countTaxaByName(String queryString,
900 // MatchMode matchMode, SelectMode selectMode, Reference sec) {
902 // Long count = countTaxaByName(queryString, matchMode, selectMode, sec, null);
903 // return count.intValue();
907 // public Integer countTaxaByName(String queryString, MatchMode matchMode, Boolean accepted) {
909 // SelectMode selectMode = (accepted ? SelectMode.TAXA : SelectMode.SYNONYMS);
910 // Long count = countTaxaByName(queryString, matchMode, selectMode, null, null);
911 // return count.intValue();
914 public List
<TaxonBase
> getAllTaxonBases(Integer pagesize
, Integer page
) {
915 return super.list(pagesize
, page
);
920 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllSynonyms(java.lang.Integer, java.lang.Integer)
922 public List
<Synonym
> getAllSynonyms(Integer limit
, Integer start
) {
923 Criteria criteria
= getSession().createCriteria(Synonym
.class);
926 criteria
.setFirstResult(start
);
927 criteria
.setMaxResults(limit
);
930 return criteria
.list();
935 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllTaxa(java.lang.Integer, java.lang.Integer)
937 public List
<Taxon
> getAllTaxa(Integer limit
, Integer start
) {
938 Criteria criteria
= getSession().createCriteria(Taxon
.class);
941 criteria
.setFirstResult(start
);
942 criteria
.setMaxResults(limit
);
945 return criteria
.list();
950 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllRelationships(java.lang.Integer, java.lang.Integer)
952 public List
<RelationshipBase
> getAllRelationships(Integer limit
, Integer start
) {
953 AuditEvent auditEvent
= getAuditEventFromContext();
954 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
955 Criteria criteria
= getSession().createCriteria(RelationshipBase
.class);
956 criteria
.setFirstResult(start
);
957 criteria
.setMaxResults(limit
);
958 return (List
<RelationshipBase
>)criteria
.list();
960 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase
.class,auditEvent
.getRevisionNumber());
961 return (List
<RelationshipBase
>)query
.getResultList();
965 /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */
966 // private boolean nullifyTaxonomicParent(Taxon taxon) {
969 // Method nullifyTaxonomicParent = taxon.getClass().getMethod("nullifyTaxonomicParent");
970 // nullifyTaxonomicParent.invoke(taxon);
971 // } catch (NoSuchMethodException ex) {
972 // logger.error("NoSuchMethod: " + ex.getMessage());
974 // } catch (IllegalArgumentException ex) {
975 // logger.error("IllegalArgumentException: " + ex.getMessage());
977 // } catch (IllegalAccessException ex) {
978 // logger.error("IllegalAccessException: " + ex.getMessage());
980 // } catch (InvocationTargetException ex) {
981 // logger.error("IllegalAccessException: " + ex.getMessage());
988 public UUID
delete(TaxonBase taxonBase
) throws DataAccessException
{
989 if (taxonBase
== null){
990 logger
.warn("TaxonBase was 'null'");
994 // Merge the object in if it is detached
996 // I think this is preferable to catching lazy initialization errors
997 // as that solution only swallows and hides the exception, but doesn't
998 // actually solve it.
999 getSession().merge(taxonBase
);
1001 if (taxonBase
instanceof Taxon
){ // is Taxon
1002 for (Iterator
<TaxonRelationship
> iterator
= ((Taxon
)taxonBase
).getRelationsFromThisTaxon().iterator(); iterator
.hasNext();){
1003 TaxonRelationship relationFromThisTaxon
= iterator
.next();
1005 // decrease children count of taxonomic parent by one
1006 if (relationFromThisTaxon
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())) {
1007 Taxon toTaxon
= relationFromThisTaxon
.getToTaxon(); // parent
1008 if (toTaxon
!= null) {
1009 toTaxon
.setTaxonomicChildrenCount(toTaxon
.getTaxonomicChildrenCount() - 1);
1015 return super.delete(taxonBase
);
1020 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, int, int, boolean)
1022 public List
<TaxonBase
> findByNameTitleCache(Class
<?
extends TaxonBase
>clazz
, String queryString
, Classification classification
, MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageNumber
, Integer pageSize
, List
<String
> propertyPaths
) {
1024 boolean doCount
= false;
1025 Query query
= prepareTaxaByName(clazz
, "titleCache", queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
1027 List
<TaxonBase
> results
= query
.list();
1028 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1031 return new ArrayList
<TaxonBase
>();
1037 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean)
1039 public int countMatchesByName(String queryString
, MatchMode matchMode
, boolean onlyAcccepted
) {
1040 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
1041 Criteria crit
= getSession().createCriteria(type
);
1042 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
1043 crit
.setProjection(Projections
.rowCount());
1044 int result
= ((Integer
)crit
.list().get(0)).intValue();
1050 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean, java.util.List)
1052 public int countMatchesByName(String queryString
, MatchMode matchMode
, boolean onlyAcccepted
, List
<Criterion
> criteria
) {
1053 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
1054 Criteria crit
= getSession().createCriteria(type
);
1055 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
1056 if(criteria
!= null){
1057 for (Criterion criterion
: criteria
) {
1058 crit
.add(criterion
);
1061 crit
.setProjection(Projections
.rowCount());
1062 int result
= ((Integer
)crit
.list().get(0)).intValue();
1068 * @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)
1070 public int countTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Direction direction
) {
1071 AuditEvent auditEvent
= getAuditEventFromContext();
1072 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1076 query
= getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction
+" = :relatedTaxon");
1078 query
= getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction
+" = :relatedTaxon and taxonRelationship.type = :type");
1079 query
.setParameter("type",type
);
1081 query
.setParameter("relatedTaxon", taxon
);
1083 return ((Long
)query
.uniqueResult()).intValue();
1085 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1086 query
.add(AuditEntity
.relatedId(direction
.toString()).eq(taxon
.getId()));
1087 query
.addProjection(AuditEntity
.id().count("id"));
1090 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1093 return ((Long
)query
.getSingleResult()).intValue();
1099 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
1101 public int countSynonyms(Taxon taxon
, SynonymRelationshipType type
) {
1102 AuditEvent auditEvent
= getAuditEventFromContext();
1103 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1104 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1106 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1108 criteria
.add(Restrictions
.eq("type", type
));
1110 criteria
.setProjection(Projections
.rowCount());
1111 return (Integer
)criteria
.uniqueResult();
1113 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1114 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1115 query
.addProjection(AuditEntity
.id().count("id"));
1118 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1121 return ((Long
)query
.getSingleResult()).intValue();
1127 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
1129 public int countSynonyms(Synonym synonym
, SynonymRelationshipType type
) {
1130 AuditEvent auditEvent
= getAuditEventFromContext();
1131 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1132 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1134 criteria
.add(Restrictions
.eq("relatedFrom", synonym
));
1136 criteria
.add(Restrictions
.eq("type", type
));
1139 criteria
.setProjection(Projections
.rowCount());
1140 return (Integer
)criteria
.uniqueResult();
1142 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1143 query
.add(AuditEntity
.relatedId("relatedFrom").eq(synonym
.getId()));
1144 query
.addProjection(AuditEntity
.id().count("id"));
1147 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1150 return ((Long
)query
.getSingleResult()).intValue();
1156 * @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)
1158 public int countTaxaByName(Class
<?
extends TaxonBase
> clazz
, String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
, Rank rank
) {
1159 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank)");
1160 Criteria criteria
= null;
1163 criteria
= getSession().createCriteria(TaxonBase
.class);
1165 criteria
= getSession().createCriteria(clazz
);
1168 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
1169 criteria
.createAlias("name", "name");
1171 if(genusOrUninomial
== null) {
1172 criteria
.add(Restrictions
.isNull("name.genusOrUninomial"));
1173 } else if(!genusOrUninomial
.equals("*")) {
1174 criteria
.add(Restrictions
.eq("name.genusOrUninomial", genusOrUninomial
));
1177 if(infraGenericEpithet
== null) {
1178 criteria
.add(Restrictions
.isNull("name.infraGenericEpithet"));
1179 } else if(!infraGenericEpithet
.equals("*")) {
1180 criteria
.add(Restrictions
.eq("name.infraGenericEpithet", infraGenericEpithet
));
1183 if(specificEpithet
== null) {
1184 criteria
.add(Restrictions
.isNull("name.specificEpithet"));
1185 } else if(!specificEpithet
.equals("*")) {
1186 criteria
.add(Restrictions
.eq("name.specificEpithet", specificEpithet
));
1190 if(infraSpecificEpithet
== null) {
1191 criteria
.add(Restrictions
.isNull("name.infraSpecificEpithet"));
1192 } else if(!infraSpecificEpithet
.equals("*")) {
1193 criteria
.add(Restrictions
.eq("name.infraSpecificEpithet", infraSpecificEpithet
));
1197 criteria
.add(Restrictions
.eq("name.rank", rank
));
1200 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
1202 return (Integer
)criteria
.uniqueResult();
1207 * @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)
1209 public List
<TaxonBase
> findTaxaByName(Class
<?
extends TaxonBase
> clazz
, String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
, Rank rank
, Integer pageSize
, Integer pageNumber
) {
1210 checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber)");
1211 Criteria criteria
= null;
1214 criteria
= getSession().createCriteria(TaxonBase
.class);
1216 criteria
= getSession().createCriteria(clazz
);
1219 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
1220 criteria
.createAlias("name", "name");
1222 if(genusOrUninomial
== null) {
1223 criteria
.add(Restrictions
.isNull("name.genusOrUninomial"));
1224 } else if(!genusOrUninomial
.equals("*")) {
1225 criteria
.add(Restrictions
.eq("name.genusOrUninomial", genusOrUninomial
));
1228 if(infraGenericEpithet
== null) {
1229 criteria
.add(Restrictions
.isNull("name.infraGenericEpithet"));
1230 } else if(!infraGenericEpithet
.equals("*")) {
1231 criteria
.add(Restrictions
.eq("name.infraGenericEpithet", infraGenericEpithet
));
1234 if(specificEpithet
== null) {
1235 criteria
.add(Restrictions
.isNull("name.specificEpithet"));
1236 } else if(!specificEpithet
.equals("*")) {
1237 criteria
.add(Restrictions
.eq("name.specificEpithet", specificEpithet
));
1241 if(infraSpecificEpithet
== null) {
1242 criteria
.add(Restrictions
.isNull("name.infraSpecificEpithet"));
1243 } else if(!infraSpecificEpithet
.equals("*")) {
1244 criteria
.add(Restrictions
.eq("name.infraSpecificEpithet", infraSpecificEpithet
));
1248 criteria
.add(Restrictions
.eq("name.rank", rank
));
1251 if(pageSize
!= null) {
1252 criteria
.setMaxResults(pageSize
);
1253 if(pageNumber
!= null) {
1254 criteria
.setFirstResult(pageNumber
* pageSize
);
1256 criteria
.setFirstResult(0);
1260 return (List
<TaxonBase
>)criteria
.list();
1265 * @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)
1267 public List
<TaxonRelationship
> getTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
, Direction direction
) {
1268 AuditEvent auditEvent
= getAuditEventFromContext();
1269 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1270 Criteria criteria
= getSession().createCriteria(TaxonRelationship
.class);
1272 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1274 criteria
.add(Restrictions
.eq("type", type
));
1277 addOrder(criteria
,orderHints
);
1279 if(pageSize
!= null) {
1280 criteria
.setMaxResults(pageSize
);
1281 if(pageNumber
!= null) {
1282 criteria
.setFirstResult(pageNumber
* pageSize
);
1284 criteria
.setFirstResult(0);
1288 List
<TaxonRelationship
> result
= (List
<TaxonRelationship
>)criteria
.list();
1289 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1293 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1294 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1297 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1300 if(pageSize
!= null) {
1301 query
.setMaxResults(pageSize
);
1302 if(pageNumber
!= null) {
1303 query
.setFirstResult(pageNumber
* pageSize
);
1305 query
.setFirstResult(0);
1309 List
<TaxonRelationship
> result
= (List
<TaxonRelationship
>)query
.getResultList();
1310 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1312 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
1313 // and we can't live without this functionality in CATE as it screws up the whole
1315 if(orderHints
!= null && !orderHints
.isEmpty()) {
1316 SortedSet
<TaxonRelationship
> sortedList
= new TreeSet
<TaxonRelationship
>(new TaxonRelationshipFromTaxonComparator());
1317 sortedList
.addAll(result
);
1318 return new ArrayList
<TaxonRelationship
>(sortedList
);
1325 class TaxonRelationshipFromTaxonComparator
implements Comparator
<TaxonRelationship
> {
1327 public int compare(TaxonRelationship o1
, TaxonRelationship o2
) {
1328 return o1
.getFromTaxon().getTitleCache().compareTo(o2
.getFromTaxon().getTitleCache());
1333 class SynonymRelationshipFromTaxonComparator
implements Comparator
<SynonymRelationship
> {
1335 public int compare(SynonymRelationship o1
, SynonymRelationship o2
) {
1336 return o1
.getSynonym().getTitleCache().compareTo(o2
.getSynonym().getTitleCache());
1343 * @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)
1345 public List
<SynonymRelationship
> getSynonyms(Taxon taxon
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1346 AuditEvent auditEvent
= getAuditEventFromContext();
1347 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1348 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1350 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1352 criteria
.add(Restrictions
.eq("type", type
));
1355 addOrder(criteria
,orderHints
);
1357 if(pageSize
!= null) {
1358 criteria
.setMaxResults(pageSize
);
1359 if(pageNumber
!= null) {
1360 criteria
.setFirstResult(pageNumber
* pageSize
);
1362 criteria
.setFirstResult(0);
1366 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
1367 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1371 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1372 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1375 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1378 if(pageSize
!= null) {
1379 query
.setMaxResults(pageSize
);
1380 if(pageNumber
!= null) {
1381 query
.setFirstResult(pageNumber
* pageSize
);
1383 query
.setFirstResult(0);
1387 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
1388 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1396 * @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)
1398 public List
<SynonymRelationship
> getSynonyms(Synonym synonym
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1399 AuditEvent auditEvent
= getAuditEventFromContext();
1400 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1401 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1403 criteria
.add(Restrictions
.eq("relatedFrom", synonym
));
1405 criteria
.add(Restrictions
.eq("type", type
));
1408 addOrder(criteria
,orderHints
);
1410 if(pageSize
!= null) {
1411 criteria
.setMaxResults(pageSize
);
1412 if(pageNumber
!= null) {
1413 criteria
.setFirstResult(pageNumber
* pageSize
);
1415 criteria
.setFirstResult(0);
1419 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
1420 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1424 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1425 query
.add(AuditEntity
.relatedId("relatedFrom").eq(synonym
.getId()));
1428 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1431 if(pageSize
!= null) {
1432 query
.setMaxResults(pageSize
);
1433 if(pageNumber
!= null) {
1434 query
.setFirstResult(pageNumber
* pageSize
);
1436 query
.setFirstResult(0);
1440 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
1441 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1448 public void rebuildIndex() {
1449 FullTextSession fullTextSession
= Search
.getFullTextSession(getSession());
1451 for(TaxonBase taxonBase
: list(null,null)) { // re-index all taxon base
1452 Hibernate
.initialize(taxonBase
.getName());
1453 fullTextSession
.index(taxonBase
);
1455 fullTextSession
.flushToIndexes();
1459 public String
suggestQuery(String queryString
) {
1460 checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
1461 String alternativeQueryString
= null;
1462 if (alternativeSpellingSuggestionParser
!= null) {
1465 alternativeSpellingSuggestionParser
.parse(queryString
);
1466 org
.apache
.lucene
.search
.Query alternativeQuery
= alternativeSpellingSuggestionParser
.suggest(queryString
);
1467 if (alternativeQuery
!= null) {
1468 alternativeQueryString
= alternativeQuery
1469 .toString("name.titleCache");
1472 } catch (ParseException e
) {
1473 throw new QueryParseException(e
, queryString
);
1476 return alternativeQueryString
;
1481 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.Classification)
1483 public List
<UuidAndTitleCache
<TaxonNode
>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification
) {
1485 int classificationId
= classification
.getId();
1487 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.classification_id = " + classificationId
;
1489 List
<Object
[]> result
= getSession().createSQLQuery(queryString
).list();
1491 if(result
.size() == 0){
1494 List
<UuidAndTitleCache
<TaxonNode
>> list
= new ArrayList
<UuidAndTitleCache
<TaxonNode
>>(result
.size());
1496 for (Object object
: result
){
1498 Object
[] objectArray
= (Object
[]) object
;
1500 UUID uuid
= UUID
.fromString((String
) objectArray
[0]);
1501 String titleCache
= (String
) objectArray
[1];
1503 list
.add(new UuidAndTitleCache(TaxonNode
.class, uuid
, titleCache
));
1511 public class UuidAndTitleCacheOfAcceptedTaxon
{
1516 public UuidAndTitleCacheOfAcceptedTaxon(UUID uuid
, String titleCache
){
1518 this.titleCache
= titleCache
;
1521 public UUID
getUuid() {
1525 public void setUuid(UUID uuid
) {
1529 public String
getTitleCache() {
1533 public void setTitleCache(String titleCache
) {
1534 this.titleCache
= titleCache
;
1539 public TaxonBase
find(LSID lsid
) {
1540 TaxonBase taxonBase
= super.find(lsid
);
1541 if(taxonBase
!= null) {
1542 List
<String
> propertyPaths
= new ArrayList
<String
>();
1543 propertyPaths
.add("createdBy");
1544 propertyPaths
.add("updatedBy");
1545 propertyPaths
.add("name");
1546 propertyPaths
.add("sec");
1547 propertyPaths
.add("relationsToThisTaxon");
1548 propertyPaths
.add("relationsToThisTaxon.fromTaxon");
1549 propertyPaths
.add("relationsToThisTaxon.toTaxon");
1550 propertyPaths
.add("relationsFromThisTaxon");
1551 propertyPaths
.add("relationsFromThisTaxon.toTaxon");
1552 propertyPaths
.add("relationsToThisTaxon.type");
1553 propertyPaths
.add("synonymRelations");
1554 propertyPaths
.add("synonymRelations.synonym");
1555 propertyPaths
.add("synonymRelations.type");
1556 propertyPaths
.add("descriptions");
1558 defaultBeanInitializer
.initialize(taxonBase
, propertyPaths
);
1563 public List
<TaxonBase
> getTaxaByCommonName(String queryString
,
1564 Classification classification
, MatchMode matchMode
,
1565 Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
) {
1566 // TODO Auto-generated method stub
1571 public List
<Synonym
> createAllInferredSynonyms(Taxon taxon
, Classification tree
){
1572 List
<Synonym
> inferredSynonyms
= new ArrayList
<Synonym
>();
1574 inferredSynonyms
.addAll(createInferredSynonyms(taxon
, tree
, SynonymRelationshipType
.INFERRED_EPITHET_OF()));
1575 inferredSynonyms
.addAll(createInferredSynonyms(taxon
, tree
, SynonymRelationshipType
.INFERRED_GENUS_OF()));
1576 inferredSynonyms
.addAll(createInferredSynonyms(taxon
, tree
, SynonymRelationshipType
.POTENTIAL_COMBINATION_OF()));
1578 return inferredSynonyms
;
1583 * Returns an existing ZoologicalName or extends an internal hashmap if it does not exist.
1584 * Very likely only useful for createInferredSynonyms().
1589 private ZoologicalName
getZoologicalName(UUID uuid
, HashMap
<UUID
, ZoologicalName
> zooHashMap
) {
1590 ZoologicalName taxonName
= this.taxonNameDao
.findZoologicalNameByUUID(uuid
);
1591 if (taxonName
== null) {
1592 taxonName
= zooHashMap
.get(uuid
);
1597 public List
<Synonym
> createInferredSynonyms(Taxon taxon
, Classification tree
, SynonymRelationshipType type
){
1598 List
<Synonym
> inferredSynonyms
= new ArrayList
<Synonym
>();
1599 List
<Synonym
> inferredSynonymsToBeRemoved
= new ArrayList
<Synonym
>();
1601 HashMap
<UUID
, ZoologicalName
> zooHashMap
= new HashMap
<UUID
, ZoologicalName
>();
1604 uuid
= taxon
.getName().getUuid();
1605 ZoologicalName taxonName
= getZoologicalName(uuid
, zooHashMap
);
1606 String epithetOfTaxon
= taxonName
.getSpecificEpithet();
1607 String genusOfTaxon
= taxonName
.getGenusOrUninomial();
1608 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
1609 List
<String
> taxonNames
= new ArrayList
<String
>();
1611 for (TaxonNode node
: nodes
){
1612 HashMap
<String
, String
> synonymsGenus
= new HashMap
<String
, String
>(); // Changed this to be able to store the idInSource to a genusName
1613 List
<String
> synonymsEpithet
= new ArrayList
<String
>();
1615 if (node
.getClassification().equals(tree
)){
1616 if (!node
.isTopmostNode()){
1617 TaxonNode parent
= (TaxonNode
)node
.getParent();
1618 parent
= (TaxonNode
)HibernateProxyHelper
.deproxy(parent
);
1619 TaxonNameBase parentName
= parent
.getTaxon().getName();
1620 parentName
= (TaxonNameBase
)HibernateProxyHelper
.deproxy(parentName
);
1622 //create inferred synonyms for species, subspecies or subgenus
1623 if (parentName
.isGenus() || parentName
.isSpecies() || parentName
.getRank().equals(Rank
.SUBGENUS())){
1625 Synonym inferredEpithet
;
1626 Synonym inferredGenus
= null;
1627 Synonym potentialCombination
;
1629 List
<String
> propertyPaths
= new ArrayList
<String
>();
1630 propertyPaths
.add("synonym");
1631 propertyPaths
.add("synonym.name");
1632 List
<OrderHint
> orderHints
= new ArrayList
<OrderHint
>();
1633 orderHints
.add(new OrderHint("relatedFrom.titleCache", SortOrder
.ASCENDING
));
1635 List
<SynonymRelationship
> synonymRelationshipsOfGenus
= getSynonyms(parent
.getTaxon(), SynonymRelationshipType
.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints
,propertyPaths
);
1636 List
<SynonymRelationship
> synonymRelationshipsOfTaxon
= getSynonyms(taxon
, SynonymRelationshipType
.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints
,propertyPaths
);
1638 if (type
.equals(SynonymRelationshipType
.INFERRED_EPITHET_OF())){
1640 for (SynonymRelationship synonymRelationOfGenus
:synonymRelationshipsOfGenus
){
1641 TaxonNameBase synName
;
1642 ZoologicalName inferredSynName
;
1643 Synonym syn
= synonymRelationOfGenus
.getSynonym();
1644 HibernateProxyHelper
.deproxy(syn
);
1646 // Determine the idInSource
1647 String idInSource
= getIdInSource(syn
);
1649 // Determine the sourceReference
1650 Reference sourceReference
= syn
.getSec();
1652 synName
= syn
.getName();
1653 ZoologicalName zooName
= getZoologicalName(synName
.getUuid(), zooHashMap
);
1654 String synGenusName
= zooName
.getGenusOrUninomial();
1655 if (synGenusName
!= null && !synonymsGenus
.containsKey(synGenusName
)){
1656 synonymsGenus
.put(synGenusName
, idInSource
);
1658 inferredSynName
= ZoologicalName
.NewInstance(Rank
.SPECIES());
1661 if (epithetOfTaxon
== null) {
1662 logger
.error("This specificEpithet is NULL");
1665 inferredSynName
.setSpecificEpithet(epithetOfTaxon
);
1666 inferredSynName
.setGenusOrUninomial(synGenusName
);
1667 inferredEpithet
= Synonym
.NewInstance(inferredSynName
, null);
1669 // Set the sourceReference
1670 inferredEpithet
.setSec(sourceReference
);
1672 // Add the original source
1673 if (idInSource
!= null) {
1674 IdentifiableSource originalSource
= IdentifiableSource
.NewInstance(idInSource
, "InferredEpithetOf", syn
.getSec(), null);
1677 Reference citation
= getCitation(syn
);
1678 if (citation
!= null) {
1679 originalSource
.setCitation(citation
);
1680 inferredEpithet
.addSource(originalSource
);
1684 taxon
.addSynonym(inferredEpithet
, SynonymRelationshipType
.INFERRED_GENUS_OF());
1685 inferredSynonyms
.add(inferredEpithet
);
1686 inferredSynName
.generateTitle();
1687 zooHashMap
.put(inferredSynName
.getUuid(), inferredSynName
);
1688 taxonNames
.add(inferredSynName
.getNameCache());
1691 if (!taxonNames
.isEmpty()){
1692 List
<String
> synNotInCDM
= this.taxaByNameNotInDB(taxonNames
);
1693 ZoologicalName name
;
1694 if (!synNotInCDM
.isEmpty()){
1695 inferredSynonymsToBeRemoved
.clear();
1697 for (Synonym syn
:inferredSynonyms
){
1698 name
= getZoologicalName(syn
.getName().getUuid(), zooHashMap
);
1699 if (!synNotInCDM
.contains(name
.getNameCache())){
1700 inferredSynonymsToBeRemoved
.add(syn
);
1704 // Remove identified Synonyms from inferredSynonyms
1705 for (Synonym synonym
: inferredSynonymsToBeRemoved
) {
1706 inferredSynonyms
.remove(synonym
);
1711 }else if (type
.equals(SynonymRelationshipType
.INFERRED_GENUS_OF())){
1714 for (SynonymRelationship synonymRelationOfTaxon
:synonymRelationshipsOfTaxon
){
1715 TaxonNameBase synName
;
1716 ZoologicalName inferredSynName
;
1718 Synonym syn
= synonymRelationOfTaxon
.getSynonym();
1719 synName
=syn
.getName();
1720 HibernateProxyHelper
.deproxy(syn
);
1722 // Determine the idInSource
1723 String idInSource
= getIdInSource(syn
);
1725 // Determine the sourceReference
1726 Reference sourceReference
= syn
.getSec();
1728 synName
= syn
.getName();
1729 ZoologicalName zooName
= getZoologicalName(synName
.getUuid(), zooHashMap
);
1730 String speciesEpithetName
= zooName
.getSpecificEpithet();
1731 if (synonymsEpithet
!= null && !synonymsEpithet
.contains(speciesEpithetName
)){
1732 synonymsEpithet
.add(speciesEpithetName
);
1734 inferredSynName
= ZoologicalName
.NewInstance(Rank
.SPECIES());
1735 inferredSynName
.setSpecificEpithet(speciesEpithetName
);
1736 inferredSynName
.setGenusOrUninomial(genusOfTaxon
);
1737 inferredGenus
= Synonym
.NewInstance(inferredSynName
, null);
1739 // Set the sourceReference
1740 inferredGenus
.setSec(sourceReference
);
1742 // Add the original source
1743 if (idInSource
!= null) {
1744 IdentifiableSource originalSource
= IdentifiableSource
.NewInstance(idInSource
, "InferredGenusOf", syn
.getSec(), null);
1747 Reference citation
= getCitation(syn
);
1748 if (citation
!= null) {
1749 originalSource
.setCitation(citation
);
1750 inferredGenus
.addSource(originalSource
);
1754 taxon
.addSynonym(inferredGenus
, SynonymRelationshipType
.INFERRED_EPITHET_OF());
1755 inferredSynonyms
.add(inferredGenus
);
1756 inferredSynName
.generateTitle();
1757 zooHashMap
.put(inferredSynName
.getUuid(), inferredSynName
);
1758 taxonNames
.add(inferredSynName
.getNameCache());
1761 if (!taxonNames
.isEmpty()){
1762 List
<String
> synNotInCDM
= this.taxaByNameNotInDB(taxonNames
);
1763 ZoologicalName name
;
1764 if (!synNotInCDM
.isEmpty()){
1765 inferredSynonymsToBeRemoved
.clear();
1767 for (Synonym syn
:inferredSynonyms
){
1768 name
= getZoologicalName(syn
.getName().getUuid(), zooHashMap
);
1769 if (!synNotInCDM
.contains(name
.getNameCache())){
1770 inferredSynonymsToBeRemoved
.add(syn
);
1774 // Remove identified Synonyms from inferredSynonyms
1775 for (Synonym synonym
: inferredSynonymsToBeRemoved
) {
1776 inferredSynonyms
.remove(synonym
);
1781 }else if (type
.equals(SynonymRelationshipType
.POTENTIAL_COMBINATION_OF())){
1783 Reference sourceReference
= null; // TODO: Determination of sourceReference is redundant
1785 for (SynonymRelationship synonymRelationOfGenus
:synonymRelationshipsOfGenus
){
1786 TaxonNameBase synName
;
1787 Synonym syn
= synonymRelationOfGenus
.getSynonym();
1788 synName
=syn
.getName();
1790 HibernateProxyHelper
.deproxy(syn
);
1792 // Set the sourceReference
1793 sourceReference
= syn
.getSec();
1795 // Determine the idInSource
1796 String idInSource
= getIdInSource(syn
);
1798 ZoologicalName zooName
= getZoologicalName(synName
.getUuid(), zooHashMap
);
1799 String synGenusName
= zooName
.getGenusOrUninomial();
1800 if (synGenusName
!= null && !synonymsGenus
.containsKey(synGenusName
)){
1801 synonymsGenus
.put(synGenusName
, idInSource
);
1805 ZoologicalName inferredSynName
;
1806 for (SynonymRelationship synonymRelationOfTaxon
:synonymRelationshipsOfTaxon
){
1808 Synonym syn
= synonymRelationOfTaxon
.getSynonym();
1809 HibernateProxyHelper
.deproxy(syn
);
1811 // Set sourceReference
1812 sourceReference
= syn
.getSec();
1814 ZoologicalName zooName
= getZoologicalName(syn
.getName().getUuid(), zooHashMap
);
1815 String epithetName
= zooName
.getSpecificEpithet();
1816 if (epithetName
!= null && !synonymsEpithet
.contains(epithetName
)){
1817 synonymsEpithet
.add(epithetName
);
1820 for (String epithetName
:synonymsEpithet
){
1821 for (String genusName
: synonymsGenus
.keySet()){
1822 inferredSynName
= ZoologicalName
.NewInstance(Rank
.SPECIES());
1823 inferredSynName
.setSpecificEpithet(epithetName
);
1824 inferredSynName
.setGenusOrUninomial(genusName
);
1825 potentialCombination
= Synonym
.NewInstance(inferredSynName
, null);
1827 // Set the sourceReference
1828 potentialCombination
.setSec(sourceReference
);
1830 // Add the original source
1831 String idInSource
= synonymsGenus
.get(genusName
);
1832 if (idInSource
!= null) {
1833 IdentifiableSource originalSource
= IdentifiableSource
.NewInstance(idInSource
, "PotentialCombinationOf", sourceReference
, null);
1836 if (sourceReference
!= null) {
1837 originalSource
.setCitation(sourceReference
);
1838 potentialCombination
.addSource(originalSource
);
1842 inferredSynonyms
.add(potentialCombination
);
1843 inferredSynName
.generateTitle();
1844 zooHashMap
.put(inferredSynName
.getUuid(), inferredSynName
);
1845 taxonNames
.add(inferredSynName
.getNameCache());
1848 if (!taxonNames
.isEmpty()){
1849 List
<String
> synNotInCDM
= this.taxaByNameNotInDB(taxonNames
);
1850 ZoologicalName name
;
1851 if (!synNotInCDM
.isEmpty()){
1852 inferredSynonymsToBeRemoved
.clear();
1854 for (Synonym syn
:inferredSynonyms
){
1856 name
= (ZoologicalName
) syn
.getName();
1857 }catch (ClassCastException e
){
1858 name
= getZoologicalName(syn
.getName().getUuid(), zooHashMap
);
1860 if (!synNotInCDM
.contains(name
.getNameCache())){
1861 inferredSynonymsToBeRemoved
.add(syn
);
1865 // Remove identified Synonyms from inferredSynonyms
1866 for (Synonym synonym
: inferredSynonymsToBeRemoved
) {
1867 inferredSynonyms
.remove(synonym
);
1873 logger
.info("The synonymrelationship type is not defined.");
1882 return inferredSynonyms
;
1887 * Returns the idInSource for a given Synonym.
1890 private String
getIdInSource(Synonym syn
) {
1891 String idInSource
= null;
1892 Set
<IdentifiableSource
> sources
= syn
.getSources();
1893 if (sources
.size() == 1) {
1894 IdentifiableSource source
= sources
.iterator().next();
1895 if (source
!= null) {
1896 idInSource
= source
.getIdInSource();
1898 } else if (sources
.size() > 1) {
1901 for (IdentifiableSource source
: sources
) {
1902 idInSource
+= source
.getIdInSource();
1903 if (count
< sources
.size()) {
1914 * Returns the citation for a given Synonym.
1917 private Reference
getCitation(Synonym syn
) {
1918 Reference citation
= null;
1919 Set
<IdentifiableSource
> sources
= syn
.getSources();
1920 if (sources
.size() == 1) {
1921 IdentifiableSource source
= sources
.iterator().next();
1922 if (source
!= null) {
1923 citation
= source
.getCitation();
1925 } else if (sources
.size() > 1) {
1926 logger
.warn("This Synonym has more than one source: " + syn
.getUuid() + " (" + syn
.getTitleCache() +")");
1932 /* private void xxx(List<SynonymRelationship> synonymRelationships, HashMap <UUID, ZoologicalName> zooHashMap, SynonymRelationshipType type, String addString){
1934 for (SynonymRelationship synonymRelation:synonymRelationships){
1935 TaxonNameBase synName;
1936 NonViralName inferredSynName;
1937 Synonym syn = synonymRelation.getSynonym();
1938 HibernateProxyHelper.deproxy(syn);
1940 synName = syn.getName();
1941 ZoologicalName zooName = zooHashMap.get(synName.getUuid());
1942 String synGenusName = zooName.getGenusOrUninomial();
1944 switch(type.getId()){
1945 case SynonymRelationshipType.INFERRED_EPITHET_OF().getId():
1946 inferredSynName.setSpecificEpithet(addString);
1948 case SynonymRelationshipType.INFERRED_GENUS_OF().getId():
1950 case SynonymRelationshipType.POTENTIAL_COMBINATION_OF().getId():
1954 if (!synonymsGenus.contains(synGenusName)){
1955 synonymsGenus.add(synGenusName);
1957 inferredSynName = NonViralName.NewInstance(Rank.SPECIES());
1958 inferredSynName.setSpecificEpithet(epithetOfTaxon);
1959 inferredSynName.setGenusOrUninomial(synGenusName);
1960 inferredEpithet = Synonym.NewInstance(inferredSynName, null);
1961 taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());
1962 inferredSynonyms.add(inferredEpithet);
1963 inferredSynName.generateTitle();
1964 taxonNames.add(inferredSynName.getNameCache());
1968 if (!taxonNames.isEmpty()){
1969 List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);
1970 ZoologicalName name;
1971 if (!synNotInCDM.isEmpty()){
1972 for (Synonym syn :inferredSynonyms){
1973 name =zooHashMap.get(syn.getName().getUuid());
1974 if (!synNotInCDM.contains(name.getNameCache())){
1975 inferredSynonyms.remove(syn);
1984 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countAllRelationships()
1986 public int countAllRelationships() {
1987 List
<RelationshipBase
> relationships
= this.getAllRelationships(null, 0);
1988 return relationships
.size();
1992 public List
<String
> taxaByNameNotInDB(List
<String
> taxonNames
){
1993 List
<TaxonBase
> notInDB
= new ArrayList
<TaxonBase
>();
1994 //get all taxa, already in db
1995 Query query
= getSession().createQuery("from TaxonNameBase t where t.nameCache IN (:taxonList)");
1996 query
.setParameterList("taxonList", taxonNames
);
1997 List
<TaxonNameBase
> taxaInDB
= query
.list();
1998 //compare the original list with the result of the query
1999 for (TaxonNameBase taxonName
: taxaInDB
){
2000 if (taxonName
.isInstanceOf(NonViralName
.class)) {
2001 NonViralName nonViralName
= CdmBase
.deproxy(taxonName
, NonViralName
.class);
2002 String nameCache
= nonViralName
.getNameCache();
2003 if (taxonNames
.contains(nameCache
)){
2004 taxonNames
.remove(nameCache
);
2012 //TODO: mal nur mit UUID probieren (ohne fetch all properties), vielleicht geht das schneller?
2013 public List
<UUID
> findIdenticalTaxonNameIds(List
<String
> propertyPaths
){
2014 Query query
=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
2015 List
<UUID
> zooNames
= query
.list();
2021 public List
<TaxonNameBase
> findIdenticalTaxonNames(List
<String
> propertyPaths
) {
2023 Query query
=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
2025 List
<TaxonNameBase
> zooNames
= query
.list();
2027 TaxonNameComparator taxComp
= new TaxonNameComparator();
2028 Collections
.sort(zooNames
, taxComp
);
2030 for (TaxonNameBase taxonNameBase
: zooNames
){
2031 defaultBeanInitializer
.initialize(taxonNameBase
, propertyPaths
);
2037 public List
<TaxonNameBase
> findIdenticalNamesNew(List
<String
> propertyPaths
){
2039 //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)
2040 Query query
= getSession().createQuery("Select id from Reference where titleCache like 'Fauna Europaea database'");
2041 List
<String
> secRefFauna
= query
.list();
2042 query
= getSession().createQuery("Select id from Reference where titleCache like 'ERMS'");
2043 List
<String
> secRefErms
= query
.list();
2044 //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");
2045 //Get all names of fauna europaea
2046 query
= getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefFauna");
2047 query
.setParameter("secRefFauna", secRefFauna
.get(0));
2048 List
<String
> namesFauna
= query
.list();
2050 //Get all names of erms
2052 query
= getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefErms");
2053 query
.setParameter("secRefErms", secRefErms
.get(0));
2055 List
<String
> namesErms
= query
.list();
2056 /*TaxonNameComparator comp = new TaxonNameComparator();
2057 Collections.sort(namesFauna);
2058 Collections.sort(namesErms);
2060 List
<String
> identicalNames
= new ArrayList
<String
>();
2061 String predecessor
= "";
2063 for (String nameFauna
: namesFauna
){
2064 if (namesErms
.contains(nameFauna
)){
2065 identicalNames
.add(nameFauna
);
2070 query
= getSession().createQuery("from ZoologicalName zn where zn.nameCache IN (:identicalNames)");
2071 query
.setParameterList("identicalNames", identicalNames
);
2072 List
<TaxonNameBase
> result
= query
.list();
2073 TaxonNameBase temp
= result
.get(0);
2075 Iterator
<OriginalSourceBase
> sources
= temp
.getSources().iterator();
2077 TaxonNameComparator taxComp
= new TaxonNameComparator();
2078 Collections
.sort(result
, taxComp
);
2079 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
2086 public String
getPhylumName(TaxonNameBase name
){
2087 List results
= new ArrayList();
2089 Query query
= getSession().createSQLQuery("select getPhylum("+ name
.getId()+");");
2090 results
= query
.list();
2091 }catch(Exception e
){
2092 System
.err
.println(name
.getUuid());
2095 System
.err
.println("phylum of "+ name
.getTitleCache() );
2096 return (String
)results
.get(0);
2100 public long countTaxaByCommonName(String searchString
,
2101 Classification classification
, MatchMode matchMode
,
2102 Set
<NamedArea
> namedAreas
) {
2103 boolean doCount
= true;
2104 Query query
= prepareTaxaByCommonName(searchString
, classification
, matchMode
, namedAreas
, null, null, doCount
);
2105 if (query
!= null && !query
.list().isEmpty()) {
2106 Object o
= query
.uniqueResult();
2116 public long deleteSynonymRelationships(Synonym syn
) {
2120 FROM RelTaxon AS RT INNER JOIN
2121 Taxon AS FaEuSyn ON RT.TaxonFk1 = FaEuSyn.TaxonId INNER JOIN
2122 Taxon AS ERMSAcc ON FaEuSyn.RankFk = ERMSAcc.RankFk AND FaEuSyn.FullName = ERMSAcc.FullName AND ISNULL(FaEuSyn.TaxonStatusFk, 0)
2123 <> ERMSAcc.TaxonStatusFk
2124 WHERE (FaEuSyn.OriginalDB = N'FaEu') AND (ERMSAcc.OriginalDB = N'ERMS') AND (ERMSAcc.TaxonStatusFk = 1) AND (ERMSAcc.KingdomFk = 2) AND
2125 (RT.RelTaxonQualifierFk > 100)
2127 Session session
= this.getSession();
2128 Query q
= session
.createQuery("delete SynonymRelationship sr where sr.relatedFrom = :syn");
2129 q
.setParameter("syn", syn
);
2130 return q
.executeUpdate();
2135 public Integer
countSynonymRelationships(TaxonBase taxonBase
,
2136 SynonymRelationshipType type
, Direction relatedfrom
) {
2137 AuditEvent auditEvent
= getAuditEventFromContext();
2138 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
2142 query
= getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom
+" = :relatedSynonym");
2144 query
= getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom
+" = :relatedSynonym and synonymRelationship.type = :type");
2145 query
.setParameter("type",type
);
2147 query
.setParameter("relatedTaxon", taxonBase
);
2149 return ((Long
)query
.uniqueResult()).intValue();
2151 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
2152 query
.add(AuditEntity
.relatedId(relatedfrom
.toString()).eq(taxonBase
.getId()));
2153 query
.addProjection(AuditEntity
.id().count("id"));
2156 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
2159 return ((Long
)query
.getSingleResult()).intValue();
2165 public List
<SynonymRelationship
> getSynonymRelationships(TaxonBase taxonBase
,
2166 SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
,
2167 List
<OrderHint
> orderHints
, List
<String
> propertyPaths
,
2168 Direction direction
) {
2170 AuditEvent auditEvent
= getAuditEventFromContext();
2171 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
2172 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
2174 if (direction
.equals(Direction
.relatedTo
)){
2175 criteria
.add(Restrictions
.eq("relatedTo", taxonBase
));
2177 criteria
.add(Restrictions
.eq("relatedFrom", taxonBase
));
2180 criteria
.add(Restrictions
.eq("type", type
));
2183 addOrder(criteria
,orderHints
);
2185 if(pageSize
!= null) {
2186 criteria
.setMaxResults(pageSize
);
2187 if(pageNumber
!= null) {
2188 criteria
.setFirstResult(pageNumber
* pageSize
);
2190 criteria
.setFirstResult(0);
2194 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
2195 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
2199 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
2201 if (direction
.equals(Direction
.relatedTo
)){
2202 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxonBase
.getId()));
2204 query
.add(AuditEntity
.relatedId("relatedFrom").eq(taxonBase
.getId()));
2208 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
2211 if(pageSize
!= null) {
2212 query
.setMaxResults(pageSize
);
2213 if(pageNumber
!= null) {
2214 query
.setFirstResult(pageNumber
* pageSize
);
2216 query
.setFirstResult(0);
2220 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
2221 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
2223 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
2224 // and we can't live without this functionality in CATE as it screws up the whole
2226 if(orderHints
!= null && !orderHints
.isEmpty()) {
2227 SortedSet
<SynonymRelationship
> sortedList
= new TreeSet
<SynonymRelationship
>(new SynonymRelationshipFromTaxonComparator());
2228 sortedList
.addAll(result
);
2229 return new ArrayList
<SynonymRelationship
>(sortedList
);
2238 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheTaxon()
2241 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheTaxon() {
2242 String queryString
= String
.format("select uuid, titleCache from %s where DTYPE = '%s'", type
.getSimpleName(), Taxon
.class.getSimpleName());
2243 Query query
= getSession().createQuery(queryString
);
2245 List
<UuidAndTitleCache
<TaxonBase
>> result
= getUuidAndTitleCache(query
);
2252 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheSynonym()
2255 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheSynonym() {
2256 String queryString
= String
.format("select uuid, titleCache from %s where DTYPE = '%s'", type
.getSimpleName(), Synonym
.class.getSimpleName());
2257 Query query
= getSession().createQuery(queryString
);
2259 List
<UuidAndTitleCache
<TaxonBase
>> result
= getUuidAndTitleCache(query
);