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){
535 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";
537 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)";
539 }else if (synonyms
.size()>0 ){
540 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t" + " where t.id in (:synonyms)";
541 } else if (taxa
.size()>0 ){
542 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t" + " where t.id in (:taxa) ";
544 hql
= "select " + selectWhat
+ " from " + clazz
.getSimpleName() + " t";
548 if (hql
== "") return null;
550 //hql += " order by t.titleCache"; //" order by t.name.nameCache";
551 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";
556 Query query
= getSession().createQuery(hql
);
559 if(clazz
.equals(Taxon
.class) && taxa
.size()>0){
561 query
.setParameterList("taxa", taxa
);
562 } else if(clazz
.equals(Synonym
.class) && synonyms
.size()>0){
564 query
.setParameterList("synonyms", synonyms
);
568 // find taxa and synonyms
570 query
.setParameterList("taxa", taxa
);
572 if (synonyms
.size()>0){
573 query
.setParameterList("synonyms",synonyms
);
575 if (taxa
.size()== 0 && synonyms
.size() == 0){
586 * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>
588 * @param classification TODO
596 * FIXME implement classification restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}
598 private Query
prepareTaxaByName(Class
<?
extends TaxonBase
> clazz
, String searchField
, String queryString
, Classification classification
,
599 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
, boolean doCount
) {
601 //TODO ? checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, Reference sec)");
603 /*String hqlQueryString = matchMode.queryStringFrom(queryString);
605 String selectWhat = (doCount ? "count(t)": "t");
608 Set<NamedArea> areasExpanded = new HashSet<NamedArea>();
609 if(namedAreas != null && namedAreas.size() > 0){
610 // expand areas and restrict by distribution area
611 List<NamedArea> childAreas;
612 Query areaQuery = getSession().createQuery("select childArea from NamedArea as childArea left join childArea.partOf as parentArea where parentArea = :area");
613 expandNamedAreas(namedAreas, areasExpanded, areaQuery);
615 boolean doAreaRestriction = areasExpanded.size() > 0;
617 Set<UUID> namedAreasUuids = new HashSet<UUID>();
618 for (NamedArea area:areasExpanded){
619 namedAreasUuids.add(area.getUuid());
622 String taxonSubselect = null;
623 String synonymSubselect = null;
625 if(classification != null){
627 if(doAreaRestriction){
629 taxonSubselect = "select t.id from" +
631 " join e.inDescription d" +
634 " join t.taxonNodes as tn "+
636 " e.area.uuid in (:namedAreasUuids) AND" +
637 " tn.classification = :classification" +
638 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
641 synonymSubselect = "select s.id from" +
643 " join e.inDescription d" +
644 " join d.taxon t" + // the taxa
645 " join t.taxonNodes as tn "+
646 " join t.synonymRelations sr" +
647 " join sr.relatedFrom s" + // the synonyms
650 " e.area.uuid in (:namedAreasUuids) AND" +
651 " tn.classification = :classification" +
652 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
656 taxonSubselect = "select t.id from" +
659 " join t.taxonNodes as tn "+
661 " tn.classification = :classification" +
662 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
664 synonymSubselect = "select s.id from" +
665 " Taxon t" + // the taxa
666 " join t.taxonNodes as tn "+
667 " join t.synonymRelations sr" +
668 " join sr.relatedFrom s" + // the synonyms
671 " tn.classification = :classification" +
672 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
676 if(doAreaRestriction){
678 taxonSubselect = "select t.id from " +
680 " join e.inDescription d" +
684 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
685 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
687 synonymSubselect = "select s.id from" +
689 " join e.inDescription d" +
690 " join d.taxon t" + // the taxa
691 " join t.synonymRelations sr" +
692 " join sr.relatedFrom s" + // the synonyms
695 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
696 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
700 taxonSubselect = "select t.id from " +
704 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
706 synonymSubselect = "select s.id from" +
707 " Taxon t" + // the taxa
708 " join t.synonymRelations sr" +
709 " join sr.relatedFrom s" + // the synonyms
712 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
721 Query subTaxon = null;
722 Query subSynonym = null;
723 if(clazz.equals(Taxon.class)){
725 subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);
726 //subTaxon = getSession().createQuery(taxonSubselect);
728 if(doAreaRestriction){
729 subTaxon.setParameterList("namedAreasUuids", namedAreasUuids);
731 if(classification != null){
732 subTaxon.setParameter("classification", classification);
734 } else if(clazz.equals(Synonym.class)){
736 subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);
738 if(doAreaRestriction){
739 subSynonym.setParameterList("namedAreasUuids", namedAreasUuids);
741 if(classification != null){
742 subSynonym.setParameter("classification", classification);
745 // find taxa and synonyms
746 subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);
747 subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);
748 if(doAreaRestriction){
749 subTaxon.setParameterList("namedAreasUuids", namedAreasUuids);
750 subSynonym.setParameterList("namedAreasUuids", namedAreasUuids);
752 if(classification != null){
753 subTaxon.setParameter("classification", classification);
754 subSynonym.setParameter("classification", classification);
758 List<Integer> taxa = new ArrayList<Integer>();
759 List<Integer> synonyms = new ArrayList<Integer>();
760 if(clazz.equals(Taxon.class)){
761 taxa = subTaxon.list();
763 }else if (clazz.equals(Synonym.class)){
764 synonyms = subSynonym.list();
766 taxa = subTaxon.list();
767 synonyms = subSynonym.list();
769 if(clazz.equals(Taxon.class)){
771 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa)";
773 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
775 } else if(clazz.equals(Synonym.class) ){
776 if (synonyms.size()>0){
777 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";
779 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
782 if(synonyms.size()>0 && taxa.size()>0){
783 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";
784 }else if (synonyms.size()>0 ){
785 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";
786 } else if (taxa.size()>0 ){
787 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) ";
789 hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";
793 if (hql == "") return null;
795 //hql += " order by t.titleCache"; //" order by t.name.nameCache";
796 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";
801 Query query = getSession().createQuery(hql);
804 if(clazz.equals(Taxon.class) && taxa.size()>0){
806 query.setParameterList("taxa", taxa );
807 } else if(clazz.equals(Synonym.class) && synonyms.size()>0){
809 query.setParameterList("synonyms", synonyms);
813 // find taxa and synonyms
815 query.setParameterList("taxa", taxa);
817 if (synonyms.size()>0){
818 query.setParameterList("synonyms",synonyms);
820 if (taxa.size()== 0 && synonyms.size() == 0){
824 Query query
= prepareQuery(clazz
, searchField
, queryString
, classification
,
825 matchMode
, namedAreas
, doCount
, false);
827 if(pageSize
!= null && !doCount
) {
828 query
.setMaxResults(pageSize
);
829 if(pageNumber
!= null) {
830 query
.setFirstResult(pageNumber
* pageSize
);
837 private Query
prepareTaxaByCommonName(String queryString
, Classification classification
,
838 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
, boolean doCount
){
840 String hql
= "from Taxon t " +
841 "join t.descriptions d "+
842 "join d.descriptionElements e " +
843 "join e.feature f " +
844 "where f.supportsCommonTaxonName = true and e.name "+matchMode
.getMatchOperator()+" :queryString";//and ls.text like 'common%'";
846 Query query
= getSession().createQuery(hql
);
848 query
.setParameter("queryString", queryString
);
850 if(pageSize
!= null && !doCount
) {
851 query
.setMaxResults(pageSize
);
852 if(pageNumber
!= null) {
853 query
.setFirstResult(pageNumber
* pageSize
);
860 * @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)
862 public long countTaxaByName(Class
<?
extends TaxonBase
> clazz
, String queryString
, Classification classification
,
863 MatchMode matchMode
, Set
<NamedArea
> namedAreas
) {
865 boolean doCount
= true;
866 Query query
= prepareTaxaByName(clazz
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, null, null, doCount
);
868 return (Long
)query
.uniqueResult();
876 * @param areasExpanded
879 private void expandNamedAreas(Collection
<NamedArea
> namedAreas
, Set
<NamedArea
> areasExpanded
, Query areaQuery
) {
880 List
<NamedArea
> childAreas
;
881 for(NamedArea a
: namedAreas
){
882 areasExpanded
.add(a
);
883 areaQuery
.setParameter("area", a
);
884 childAreas
= areaQuery
.list();
885 if(childAreas
.size() > 0){
886 areasExpanded
.addAll(childAreas
);
887 expandNamedAreas(childAreas
, areasExpanded
, areaQuery
);
893 // * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode)
895 // public Integer countTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode) {
896 // return countTaxaByName(queryString, matchMode, selectMode, null);
900 // * @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)
902 // public Integer countTaxaByName(String queryString,
903 // MatchMode matchMode, SelectMode selectMode, Reference sec) {
905 // Long count = countTaxaByName(queryString, matchMode, selectMode, sec, null);
906 // return count.intValue();
910 // public Integer countTaxaByName(String queryString, MatchMode matchMode, Boolean accepted) {
912 // SelectMode selectMode = (accepted ? SelectMode.TAXA : SelectMode.SYNONYMS);
913 // Long count = countTaxaByName(queryString, matchMode, selectMode, null, null);
914 // return count.intValue();
917 public List
<TaxonBase
> getAllTaxonBases(Integer pagesize
, Integer page
) {
918 return super.list(pagesize
, page
);
923 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllSynonyms(java.lang.Integer, java.lang.Integer)
925 public List
<Synonym
> getAllSynonyms(Integer limit
, Integer start
) {
926 Criteria criteria
= getSession().createCriteria(Synonym
.class);
929 criteria
.setFirstResult(start
);
930 criteria
.setMaxResults(limit
);
933 return criteria
.list();
938 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllTaxa(java.lang.Integer, java.lang.Integer)
940 public List
<Taxon
> getAllTaxa(Integer limit
, Integer start
) {
941 Criteria criteria
= getSession().createCriteria(Taxon
.class);
944 criteria
.setFirstResult(start
);
945 criteria
.setMaxResults(limit
);
948 return criteria
.list();
953 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllRelationships(java.lang.Integer, java.lang.Integer)
955 public List
<RelationshipBase
> getAllRelationships(Integer limit
, Integer start
) {
956 AuditEvent auditEvent
= getAuditEventFromContext();
957 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
958 Criteria criteria
= getSession().createCriteria(RelationshipBase
.class);
959 criteria
.setFirstResult(start
);
960 criteria
.setMaxResults(limit
);
961 return (List
<RelationshipBase
>)criteria
.list();
963 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase
.class,auditEvent
.getRevisionNumber());
964 return (List
<RelationshipBase
>)query
.getResultList();
968 /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */
969 // private boolean nullifyTaxonomicParent(Taxon taxon) {
972 // Method nullifyTaxonomicParent = taxon.getClass().getMethod("nullifyTaxonomicParent");
973 // nullifyTaxonomicParent.invoke(taxon);
974 // } catch (NoSuchMethodException ex) {
975 // logger.error("NoSuchMethod: " + ex.getMessage());
977 // } catch (IllegalArgumentException ex) {
978 // logger.error("IllegalArgumentException: " + ex.getMessage());
980 // } catch (IllegalAccessException ex) {
981 // logger.error("IllegalAccessException: " + ex.getMessage());
983 // } catch (InvocationTargetException ex) {
984 // logger.error("IllegalAccessException: " + ex.getMessage());
991 public UUID
delete(TaxonBase taxonBase
) throws DataAccessException
{
992 if (taxonBase
== null){
993 logger
.warn("TaxonBase was 'null'");
997 // Merge the object in if it is detached
999 // I think this is preferable to catching lazy initialization errors
1000 // as that solution only swallows and hides the exception, but doesn't
1001 // actually solve it.
1002 getSession().merge(taxonBase
);
1004 if (taxonBase
instanceof Taxon
){ // is Taxon
1005 for (Iterator
<TaxonRelationship
> iterator
= ((Taxon
)taxonBase
).getRelationsFromThisTaxon().iterator(); iterator
.hasNext();){
1006 TaxonRelationship relationFromThisTaxon
= iterator
.next();
1008 // decrease children count of taxonomic parent by one
1009 if (relationFromThisTaxon
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())) {
1010 Taxon toTaxon
= relationFromThisTaxon
.getToTaxon(); // parent
1011 if (toTaxon
!= null) {
1012 toTaxon
.setTaxonomicChildrenCount(toTaxon
.getTaxonomicChildrenCount() - 1);
1018 return super.delete(taxonBase
);
1023 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, int, int, boolean)
1025 public List
<TaxonBase
> findByNameTitleCache(Class
<?
extends TaxonBase
>clazz
, String queryString
, Classification classification
, MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageNumber
, Integer pageSize
, List
<String
> propertyPaths
) {
1027 boolean doCount
= false;
1028 Query query
= prepareTaxaByName(clazz
, "titleCache", queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
1030 List
<TaxonBase
> results
= query
.list();
1031 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1034 return new ArrayList
<TaxonBase
>();
1040 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean)
1042 public int countMatchesByName(String queryString
, MatchMode matchMode
, boolean onlyAcccepted
) {
1043 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
1044 Criteria crit
= getSession().createCriteria(type
);
1045 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
1046 crit
.setProjection(Projections
.rowCount());
1047 int result
= ((Integer
)crit
.list().get(0)).intValue();
1053 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean, java.util.List)
1055 public int countMatchesByName(String queryString
, MatchMode matchMode
, boolean onlyAcccepted
, List
<Criterion
> criteria
) {
1056 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
1057 Criteria crit
= getSession().createCriteria(type
);
1058 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
1059 if(criteria
!= null){
1060 for (Criterion criterion
: criteria
) {
1061 crit
.add(criterion
);
1064 crit
.setProjection(Projections
.rowCount());
1065 int result
= ((Integer
)crit
.list().get(0)).intValue();
1071 * @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)
1073 public int countTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Direction direction
) {
1074 AuditEvent auditEvent
= getAuditEventFromContext();
1075 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1079 query
= getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction
+" = :relatedTaxon");
1081 query
= getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction
+" = :relatedTaxon and taxonRelationship.type = :type");
1082 query
.setParameter("type",type
);
1084 query
.setParameter("relatedTaxon", taxon
);
1086 return ((Long
)query
.uniqueResult()).intValue();
1088 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1089 query
.add(AuditEntity
.relatedId(direction
.toString()).eq(taxon
.getId()));
1090 query
.addProjection(AuditEntity
.id().count("id"));
1093 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1096 return ((Long
)query
.getSingleResult()).intValue();
1102 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
1104 public int countSynonyms(Taxon taxon
, SynonymRelationshipType type
) {
1105 AuditEvent auditEvent
= getAuditEventFromContext();
1106 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1107 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1109 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1111 criteria
.add(Restrictions
.eq("type", type
));
1113 criteria
.setProjection(Projections
.rowCount());
1114 return (Integer
)criteria
.uniqueResult();
1116 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1117 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1118 query
.addProjection(AuditEntity
.id().count("id"));
1121 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1124 return ((Long
)query
.getSingleResult()).intValue();
1130 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
1132 public int countSynonyms(Synonym synonym
, SynonymRelationshipType type
) {
1133 AuditEvent auditEvent
= getAuditEventFromContext();
1134 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1135 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1137 criteria
.add(Restrictions
.eq("relatedFrom", synonym
));
1139 criteria
.add(Restrictions
.eq("type", type
));
1142 criteria
.setProjection(Projections
.rowCount());
1143 return (Integer
)criteria
.uniqueResult();
1145 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1146 query
.add(AuditEntity
.relatedId("relatedFrom").eq(synonym
.getId()));
1147 query
.addProjection(AuditEntity
.id().count("id"));
1150 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1153 return ((Long
)query
.getSingleResult()).intValue();
1159 * @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)
1161 public int countTaxaByName(Class
<?
extends TaxonBase
> clazz
, String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
, Rank rank
) {
1162 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank)");
1163 Criteria criteria
= null;
1166 criteria
= getSession().createCriteria(TaxonBase
.class);
1168 criteria
= getSession().createCriteria(clazz
);
1171 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
1172 criteria
.createAlias("name", "name");
1174 if(genusOrUninomial
== null) {
1175 criteria
.add(Restrictions
.isNull("name.genusOrUninomial"));
1176 } else if(!genusOrUninomial
.equals("*")) {
1177 criteria
.add(Restrictions
.eq("name.genusOrUninomial", genusOrUninomial
));
1180 if(infraGenericEpithet
== null) {
1181 criteria
.add(Restrictions
.isNull("name.infraGenericEpithet"));
1182 } else if(!infraGenericEpithet
.equals("*")) {
1183 criteria
.add(Restrictions
.eq("name.infraGenericEpithet", infraGenericEpithet
));
1186 if(specificEpithet
== null) {
1187 criteria
.add(Restrictions
.isNull("name.specificEpithet"));
1188 } else if(!specificEpithet
.equals("*")) {
1189 criteria
.add(Restrictions
.eq("name.specificEpithet", specificEpithet
));
1193 if(infraSpecificEpithet
== null) {
1194 criteria
.add(Restrictions
.isNull("name.infraSpecificEpithet"));
1195 } else if(!infraSpecificEpithet
.equals("*")) {
1196 criteria
.add(Restrictions
.eq("name.infraSpecificEpithet", infraSpecificEpithet
));
1200 criteria
.add(Restrictions
.eq("name.rank", rank
));
1203 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
1205 return (Integer
)criteria
.uniqueResult();
1210 * @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)
1212 public List
<TaxonBase
> findTaxaByName(Class
<?
extends TaxonBase
> clazz
, String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
, Rank rank
, Integer pageSize
, Integer pageNumber
) {
1213 checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber)");
1214 Criteria criteria
= null;
1217 criteria
= getSession().createCriteria(TaxonBase
.class);
1219 criteria
= getSession().createCriteria(clazz
);
1222 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
1223 criteria
.createAlias("name", "name");
1225 if(genusOrUninomial
== null) {
1226 criteria
.add(Restrictions
.isNull("name.genusOrUninomial"));
1227 } else if(!genusOrUninomial
.equals("*")) {
1228 criteria
.add(Restrictions
.eq("name.genusOrUninomial", genusOrUninomial
));
1231 if(infraGenericEpithet
== null) {
1232 criteria
.add(Restrictions
.isNull("name.infraGenericEpithet"));
1233 } else if(!infraGenericEpithet
.equals("*")) {
1234 criteria
.add(Restrictions
.eq("name.infraGenericEpithet", infraGenericEpithet
));
1237 if(specificEpithet
== null) {
1238 criteria
.add(Restrictions
.isNull("name.specificEpithet"));
1239 } else if(!specificEpithet
.equals("*")) {
1240 criteria
.add(Restrictions
.eq("name.specificEpithet", specificEpithet
));
1244 if(infraSpecificEpithet
== null) {
1245 criteria
.add(Restrictions
.isNull("name.infraSpecificEpithet"));
1246 } else if(!infraSpecificEpithet
.equals("*")) {
1247 criteria
.add(Restrictions
.eq("name.infraSpecificEpithet", infraSpecificEpithet
));
1251 criteria
.add(Restrictions
.eq("name.rank", rank
));
1254 if(pageSize
!= null) {
1255 criteria
.setMaxResults(pageSize
);
1256 if(pageNumber
!= null) {
1257 criteria
.setFirstResult(pageNumber
* pageSize
);
1259 criteria
.setFirstResult(0);
1263 return (List
<TaxonBase
>)criteria
.list();
1268 * @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)
1270 public List
<TaxonRelationship
> getTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
, Direction direction
) {
1271 AuditEvent auditEvent
= getAuditEventFromContext();
1272 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1273 Criteria criteria
= getSession().createCriteria(TaxonRelationship
.class);
1275 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1277 criteria
.add(Restrictions
.eq("type", type
));
1280 addOrder(criteria
,orderHints
);
1282 if(pageSize
!= null) {
1283 criteria
.setMaxResults(pageSize
);
1284 if(pageNumber
!= null) {
1285 criteria
.setFirstResult(pageNumber
* pageSize
);
1287 criteria
.setFirstResult(0);
1291 List
<TaxonRelationship
> result
= (List
<TaxonRelationship
>)criteria
.list();
1292 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1296 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1297 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1300 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1303 if(pageSize
!= null) {
1304 query
.setMaxResults(pageSize
);
1305 if(pageNumber
!= null) {
1306 query
.setFirstResult(pageNumber
* pageSize
);
1308 query
.setFirstResult(0);
1312 List
<TaxonRelationship
> result
= (List
<TaxonRelationship
>)query
.getResultList();
1313 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1315 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
1316 // and we can't live without this functionality in CATE as it screws up the whole
1318 if(orderHints
!= null && !orderHints
.isEmpty()) {
1319 SortedSet
<TaxonRelationship
> sortedList
= new TreeSet
<TaxonRelationship
>(new TaxonRelationshipFromTaxonComparator());
1320 sortedList
.addAll(result
);
1321 return new ArrayList
<TaxonRelationship
>(sortedList
);
1328 class TaxonRelationshipFromTaxonComparator
implements Comparator
<TaxonRelationship
> {
1330 public int compare(TaxonRelationship o1
, TaxonRelationship o2
) {
1331 return o1
.getFromTaxon().getTitleCache().compareTo(o2
.getFromTaxon().getTitleCache());
1336 class SynonymRelationshipFromTaxonComparator
implements Comparator
<SynonymRelationship
> {
1338 public int compare(SynonymRelationship o1
, SynonymRelationship o2
) {
1339 return o1
.getSynonym().getTitleCache().compareTo(o2
.getSynonym().getTitleCache());
1346 * @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)
1348 public List
<SynonymRelationship
> getSynonyms(Taxon taxon
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1349 AuditEvent auditEvent
= getAuditEventFromContext();
1350 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1351 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1353 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1355 criteria
.add(Restrictions
.eq("type", type
));
1358 addOrder(criteria
,orderHints
);
1360 if(pageSize
!= null) {
1361 criteria
.setMaxResults(pageSize
);
1362 if(pageNumber
!= null) {
1363 criteria
.setFirstResult(pageNumber
* pageSize
);
1365 criteria
.setFirstResult(0);
1369 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
1370 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1374 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1375 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1378 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1381 if(pageSize
!= null) {
1382 query
.setMaxResults(pageSize
);
1383 if(pageNumber
!= null) {
1384 query
.setFirstResult(pageNumber
* pageSize
);
1386 query
.setFirstResult(0);
1390 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
1391 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1399 * @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)
1401 public List
<SynonymRelationship
> getSynonyms(Synonym synonym
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1402 AuditEvent auditEvent
= getAuditEventFromContext();
1403 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1404 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1406 criteria
.add(Restrictions
.eq("relatedFrom", synonym
));
1408 criteria
.add(Restrictions
.eq("type", type
));
1411 addOrder(criteria
,orderHints
);
1413 if(pageSize
!= null) {
1414 criteria
.setMaxResults(pageSize
);
1415 if(pageNumber
!= null) {
1416 criteria
.setFirstResult(pageNumber
* pageSize
);
1418 criteria
.setFirstResult(0);
1422 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
1423 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1427 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1428 query
.add(AuditEntity
.relatedId("relatedFrom").eq(synonym
.getId()));
1431 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1434 if(pageSize
!= null) {
1435 query
.setMaxResults(pageSize
);
1436 if(pageNumber
!= null) {
1437 query
.setFirstResult(pageNumber
* pageSize
);
1439 query
.setFirstResult(0);
1443 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
1444 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1451 public void rebuildIndex() {
1452 FullTextSession fullTextSession
= Search
.getFullTextSession(getSession());
1454 for(TaxonBase taxonBase
: list(null,null)) { // re-index all taxon base
1455 Hibernate
.initialize(taxonBase
.getName());
1456 fullTextSession
.index(taxonBase
);
1458 fullTextSession
.flushToIndexes();
1462 public String
suggestQuery(String queryString
) {
1463 checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
1464 String alternativeQueryString
= null;
1465 if (alternativeSpellingSuggestionParser
!= null) {
1468 alternativeSpellingSuggestionParser
.parse(queryString
);
1469 org
.apache
.lucene
.search
.Query alternativeQuery
= alternativeSpellingSuggestionParser
.suggest(queryString
);
1470 if (alternativeQuery
!= null) {
1471 alternativeQueryString
= alternativeQuery
1472 .toString("name.titleCache");
1475 } catch (ParseException e
) {
1476 throw new QueryParseException(e
, queryString
);
1479 return alternativeQueryString
;
1484 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.Classification)
1486 public List
<UuidAndTitleCache
<TaxonNode
>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification
) {
1488 int classificationId
= classification
.getId();
1490 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
;
1492 List
<Object
[]> result
= getSession().createSQLQuery(queryString
).list();
1494 if(result
.size() == 0){
1497 List
<UuidAndTitleCache
<TaxonNode
>> list
= new ArrayList
<UuidAndTitleCache
<TaxonNode
>>(result
.size());
1499 for (Object object
: result
){
1501 Object
[] objectArray
= (Object
[]) object
;
1503 UUID uuid
= UUID
.fromString((String
) objectArray
[0]);
1504 String titleCache
= (String
) objectArray
[1];
1506 list
.add(new UuidAndTitleCache(TaxonNode
.class, uuid
, titleCache
));
1514 public class UuidAndTitleCacheOfAcceptedTaxon
{
1519 public UuidAndTitleCacheOfAcceptedTaxon(UUID uuid
, String titleCache
){
1521 this.titleCache
= titleCache
;
1524 public UUID
getUuid() {
1528 public void setUuid(UUID uuid
) {
1532 public String
getTitleCache() {
1536 public void setTitleCache(String titleCache
) {
1537 this.titleCache
= titleCache
;
1542 public TaxonBase
find(LSID lsid
) {
1543 TaxonBase taxonBase
= super.find(lsid
);
1544 if(taxonBase
!= null) {
1545 List
<String
> propertyPaths
= new ArrayList
<String
>();
1546 propertyPaths
.add("createdBy");
1547 propertyPaths
.add("updatedBy");
1548 propertyPaths
.add("name");
1549 propertyPaths
.add("sec");
1550 propertyPaths
.add("relationsToThisTaxon");
1551 propertyPaths
.add("relationsToThisTaxon.fromTaxon");
1552 propertyPaths
.add("relationsToThisTaxon.toTaxon");
1553 propertyPaths
.add("relationsFromThisTaxon");
1554 propertyPaths
.add("relationsFromThisTaxon.toTaxon");
1555 propertyPaths
.add("relationsToThisTaxon.type");
1556 propertyPaths
.add("synonymRelations");
1557 propertyPaths
.add("synonymRelations.synonym");
1558 propertyPaths
.add("synonymRelations.type");
1559 propertyPaths
.add("descriptions");
1561 defaultBeanInitializer
.initialize(taxonBase
, propertyPaths
);
1566 public List
<TaxonBase
> getTaxaByCommonName(String queryString
,
1567 Classification classification
, MatchMode matchMode
,
1568 Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
) {
1569 // TODO Auto-generated method stub
1574 public List
<Synonym
> createAllInferredSynonyms(Taxon taxon
, Classification tree
){
1575 List
<Synonym
> inferredSynonyms
= new ArrayList
<Synonym
>();
1577 inferredSynonyms
.addAll(createInferredSynonyms(taxon
, tree
, SynonymRelationshipType
.INFERRED_EPITHET_OF()));
1578 inferredSynonyms
.addAll(createInferredSynonyms(taxon
, tree
, SynonymRelationshipType
.INFERRED_GENUS_OF()));
1579 inferredSynonyms
.addAll(createInferredSynonyms(taxon
, tree
, SynonymRelationshipType
.POTENTIAL_COMBINATION_OF()));
1581 return inferredSynonyms
;
1586 * Returns an existing ZoologicalName or extends an internal hashmap if it does not exist.
1587 * Very likely only useful for createInferredSynonyms().
1592 private ZoologicalName
getZoologicalName(UUID uuid
, HashMap
<UUID
, ZoologicalName
> zooHashMap
) {
1593 ZoologicalName taxonName
= this.taxonNameDao
.findZoologicalNameByUUID(uuid
);
1594 if (taxonName
== null) {
1595 taxonName
= zooHashMap
.get(uuid
);
1600 public List
<Synonym
> createInferredSynonyms(Taxon taxon
, Classification tree
, SynonymRelationshipType type
){
1601 List
<Synonym
> inferredSynonyms
= new ArrayList
<Synonym
>();
1602 List
<Synonym
> inferredSynonymsToBeRemoved
= new ArrayList
<Synonym
>();
1604 HashMap
<UUID
, ZoologicalName
> zooHashMap
= new HashMap
<UUID
, ZoologicalName
>();
1607 uuid
= taxon
.getName().getUuid();
1608 ZoologicalName taxonName
= getZoologicalName(uuid
, zooHashMap
);
1609 String epithetOfTaxon
= taxonName
.getSpecificEpithet();
1610 String genusOfTaxon
= taxonName
.getGenusOrUninomial();
1611 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
1612 List
<String
> taxonNames
= new ArrayList
<String
>();
1614 for (TaxonNode node
: nodes
){
1615 HashMap
<String
, String
> synonymsGenus
= new HashMap
<String
, String
>(); // Changed this to be able to store the idInSource to a genusName
1616 List
<String
> synonymsEpithet
= new ArrayList
<String
>();
1618 if (node
.getClassification().equals(tree
)){
1619 if (!node
.isTopmostNode()){
1620 TaxonNode parent
= (TaxonNode
)node
.getParent();
1621 parent
= (TaxonNode
)HibernateProxyHelper
.deproxy(parent
);
1622 TaxonNameBase parentName
= parent
.getTaxon().getName();
1623 parentName
= (TaxonNameBase
)HibernateProxyHelper
.deproxy(parentName
);
1625 //create inferred synonyms for species, subspecies or subgenus
1626 if (parentName
.isGenus() || parentName
.isSpecies() || parentName
.getRank().equals(Rank
.SUBGENUS())){
1628 Synonym inferredEpithet
;
1629 Synonym inferredGenus
= null;
1630 Synonym potentialCombination
;
1632 List
<String
> propertyPaths
= new ArrayList
<String
>();
1633 propertyPaths
.add("synonym");
1634 propertyPaths
.add("synonym.name");
1635 List
<OrderHint
> orderHints
= new ArrayList
<OrderHint
>();
1636 orderHints
.add(new OrderHint("relatedFrom.titleCache", SortOrder
.ASCENDING
));
1638 List
<SynonymRelationship
> synonymRelationshipsOfGenus
= getSynonyms(parent
.getTaxon(), SynonymRelationshipType
.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints
,propertyPaths
);
1639 List
<SynonymRelationship
> synonymRelationshipsOfTaxon
= getSynonyms(taxon
, SynonymRelationshipType
.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints
,propertyPaths
);
1641 if (type
.equals(SynonymRelationshipType
.INFERRED_EPITHET_OF())){
1643 for (SynonymRelationship synonymRelationOfGenus
:synonymRelationshipsOfGenus
){
1644 TaxonNameBase synName
;
1645 ZoologicalName inferredSynName
;
1646 Synonym syn
= synonymRelationOfGenus
.getSynonym();
1647 HibernateProxyHelper
.deproxy(syn
);
1649 // Determine the idInSource
1650 String idInSource
= getIdInSource(syn
);
1652 // Determine the sourceReference
1653 Reference sourceReference
= syn
.getSec();
1655 synName
= syn
.getName();
1656 ZoologicalName zooName
= getZoologicalName(synName
.getUuid(), zooHashMap
);
1657 String synGenusName
= zooName
.getGenusOrUninomial();
1658 if (synGenusName
!= null && !synonymsGenus
.containsKey(synGenusName
)){
1659 synonymsGenus
.put(synGenusName
, idInSource
);
1661 inferredSynName
= ZoologicalName
.NewInstance(Rank
.SPECIES());
1664 if (epithetOfTaxon
== null) {
1665 logger
.error("This specificEpithet is NULL");
1668 inferredSynName
.setSpecificEpithet(epithetOfTaxon
);
1669 inferredSynName
.setGenusOrUninomial(synGenusName
);
1670 inferredEpithet
= Synonym
.NewInstance(inferredSynName
, null);
1672 // Set the sourceReference
1673 inferredEpithet
.setSec(sourceReference
);
1675 // Add the original source
1676 if (idInSource
!= null) {
1677 IdentifiableSource originalSource
= IdentifiableSource
.NewInstance(idInSource
, "InferredEpithetOf", syn
.getSec(), null);
1680 Reference citation
= getCitation(syn
);
1681 if (citation
!= null) {
1682 originalSource
.setCitation(citation
);
1683 inferredEpithet
.addSource(originalSource
);
1687 taxon
.addSynonym(inferredEpithet
, SynonymRelationshipType
.INFERRED_GENUS_OF());
1688 inferredSynonyms
.add(inferredEpithet
);
1689 inferredSynName
.generateTitle();
1690 zooHashMap
.put(inferredSynName
.getUuid(), inferredSynName
);
1691 taxonNames
.add(inferredSynName
.getNameCache());
1694 if (!taxonNames
.isEmpty()){
1695 List
<String
> synNotInCDM
= this.taxaByNameNotInDB(taxonNames
);
1696 ZoologicalName name
;
1697 if (!synNotInCDM
.isEmpty()){
1698 inferredSynonymsToBeRemoved
.clear();
1700 for (Synonym syn
:inferredSynonyms
){
1701 name
= getZoologicalName(syn
.getName().getUuid(), zooHashMap
);
1702 if (!synNotInCDM
.contains(name
.getNameCache())){
1703 inferredSynonymsToBeRemoved
.add(syn
);
1707 // Remove identified Synonyms from inferredSynonyms
1708 for (Synonym synonym
: inferredSynonymsToBeRemoved
) {
1709 inferredSynonyms
.remove(synonym
);
1714 }else if (type
.equals(SynonymRelationshipType
.INFERRED_GENUS_OF())){
1717 for (SynonymRelationship synonymRelationOfTaxon
:synonymRelationshipsOfTaxon
){
1718 TaxonNameBase synName
;
1719 ZoologicalName inferredSynName
;
1721 Synonym syn
= synonymRelationOfTaxon
.getSynonym();
1722 synName
=syn
.getName();
1723 HibernateProxyHelper
.deproxy(syn
);
1725 // Determine the idInSource
1726 String idInSource
= getIdInSource(syn
);
1728 // Determine the sourceReference
1729 Reference sourceReference
= syn
.getSec();
1731 synName
= syn
.getName();
1732 ZoologicalName zooName
= getZoologicalName(synName
.getUuid(), zooHashMap
);
1733 String speciesEpithetName
= zooName
.getSpecificEpithet();
1734 if (synonymsEpithet
!= null && !synonymsEpithet
.contains(speciesEpithetName
)){
1735 synonymsEpithet
.add(speciesEpithetName
);
1737 inferredSynName
= ZoologicalName
.NewInstance(Rank
.SPECIES());
1738 inferredSynName
.setSpecificEpithet(speciesEpithetName
);
1739 inferredSynName
.setGenusOrUninomial(genusOfTaxon
);
1740 inferredGenus
= Synonym
.NewInstance(inferredSynName
, null);
1742 // Set the sourceReference
1743 inferredGenus
.setSec(sourceReference
);
1745 // Add the original source
1746 if (idInSource
!= null) {
1747 IdentifiableSource originalSource
= IdentifiableSource
.NewInstance(idInSource
, "InferredGenusOf", syn
.getSec(), null);
1750 Reference citation
= getCitation(syn
);
1751 if (citation
!= null) {
1752 originalSource
.setCitation(citation
);
1753 inferredGenus
.addSource(originalSource
);
1757 taxon
.addSynonym(inferredGenus
, SynonymRelationshipType
.INFERRED_EPITHET_OF());
1758 inferredSynonyms
.add(inferredGenus
);
1759 inferredSynName
.generateTitle();
1760 zooHashMap
.put(inferredSynName
.getUuid(), inferredSynName
);
1761 taxonNames
.add(inferredSynName
.getNameCache());
1764 if (!taxonNames
.isEmpty()){
1765 List
<String
> synNotInCDM
= this.taxaByNameNotInDB(taxonNames
);
1766 ZoologicalName name
;
1767 if (!synNotInCDM
.isEmpty()){
1768 inferredSynonymsToBeRemoved
.clear();
1770 for (Synonym syn
:inferredSynonyms
){
1771 name
= getZoologicalName(syn
.getName().getUuid(), zooHashMap
);
1772 if (!synNotInCDM
.contains(name
.getNameCache())){
1773 inferredSynonymsToBeRemoved
.add(syn
);
1777 // Remove identified Synonyms from inferredSynonyms
1778 for (Synonym synonym
: inferredSynonymsToBeRemoved
) {
1779 inferredSynonyms
.remove(synonym
);
1784 }else if (type
.equals(SynonymRelationshipType
.POTENTIAL_COMBINATION_OF())){
1786 Reference sourceReference
= null; // TODO: Determination of sourceReference is redundant
1788 for (SynonymRelationship synonymRelationOfGenus
:synonymRelationshipsOfGenus
){
1789 TaxonNameBase synName
;
1790 Synonym syn
= synonymRelationOfGenus
.getSynonym();
1791 synName
=syn
.getName();
1793 HibernateProxyHelper
.deproxy(syn
);
1795 // Set the sourceReference
1796 sourceReference
= syn
.getSec();
1798 // Determine the idInSource
1799 String idInSource
= getIdInSource(syn
);
1801 ZoologicalName zooName
= getZoologicalName(synName
.getUuid(), zooHashMap
);
1802 String synGenusName
= zooName
.getGenusOrUninomial();
1803 if (synGenusName
!= null && !synonymsGenus
.containsKey(synGenusName
)){
1804 synonymsGenus
.put(synGenusName
, idInSource
);
1808 ZoologicalName inferredSynName
;
1809 for (SynonymRelationship synonymRelationOfTaxon
:synonymRelationshipsOfTaxon
){
1811 Synonym syn
= synonymRelationOfTaxon
.getSynonym();
1812 HibernateProxyHelper
.deproxy(syn
);
1814 // Set sourceReference
1815 sourceReference
= syn
.getSec();
1817 ZoologicalName zooName
= getZoologicalName(syn
.getName().getUuid(), zooHashMap
);
1818 String epithetName
= zooName
.getSpecificEpithet();
1819 if (epithetName
!= null && !synonymsEpithet
.contains(epithetName
)){
1820 synonymsEpithet
.add(epithetName
);
1823 for (String epithetName
:synonymsEpithet
){
1824 for (String genusName
: synonymsGenus
.keySet()){
1825 inferredSynName
= ZoologicalName
.NewInstance(Rank
.SPECIES());
1826 inferredSynName
.setSpecificEpithet(epithetName
);
1827 inferredSynName
.setGenusOrUninomial(genusName
);
1828 potentialCombination
= Synonym
.NewInstance(inferredSynName
, null);
1830 // Set the sourceReference
1831 potentialCombination
.setSec(sourceReference
);
1833 // Add the original source
1834 String idInSource
= synonymsGenus
.get(genusName
);
1835 if (idInSource
!= null) {
1836 IdentifiableSource originalSource
= IdentifiableSource
.NewInstance(idInSource
, "PotentialCombinationOf", sourceReference
, null);
1839 if (sourceReference
!= null) {
1840 originalSource
.setCitation(sourceReference
);
1841 potentialCombination
.addSource(originalSource
);
1845 inferredSynonyms
.add(potentialCombination
);
1846 inferredSynName
.generateTitle();
1847 zooHashMap
.put(inferredSynName
.getUuid(), inferredSynName
);
1848 taxonNames
.add(inferredSynName
.getNameCache());
1851 if (!taxonNames
.isEmpty()){
1852 List
<String
> synNotInCDM
= this.taxaByNameNotInDB(taxonNames
);
1853 ZoologicalName name
;
1854 if (!synNotInCDM
.isEmpty()){
1855 inferredSynonymsToBeRemoved
.clear();
1857 for (Synonym syn
:inferredSynonyms
){
1859 name
= (ZoologicalName
) syn
.getName();
1860 }catch (ClassCastException e
){
1861 name
= getZoologicalName(syn
.getName().getUuid(), zooHashMap
);
1863 if (!synNotInCDM
.contains(name
.getNameCache())){
1864 inferredSynonymsToBeRemoved
.add(syn
);
1868 // Remove identified Synonyms from inferredSynonyms
1869 for (Synonym synonym
: inferredSynonymsToBeRemoved
) {
1870 inferredSynonyms
.remove(synonym
);
1876 logger
.info("The synonymrelationship type is not defined.");
1885 return inferredSynonyms
;
1890 * Returns the idInSource for a given Synonym.
1893 private String
getIdInSource(Synonym syn
) {
1894 String idInSource
= null;
1895 Set
<IdentifiableSource
> sources
= syn
.getSources();
1896 if (sources
.size() == 1) {
1897 IdentifiableSource source
= sources
.iterator().next();
1898 if (source
!= null) {
1899 idInSource
= source
.getIdInSource();
1901 } else if (sources
.size() > 1) {
1904 for (IdentifiableSource source
: sources
) {
1905 idInSource
+= source
.getIdInSource();
1906 if (count
< sources
.size()) {
1917 * Returns the citation for a given Synonym.
1920 private Reference
getCitation(Synonym syn
) {
1921 Reference citation
= null;
1922 Set
<IdentifiableSource
> sources
= syn
.getSources();
1923 if (sources
.size() == 1) {
1924 IdentifiableSource source
= sources
.iterator().next();
1925 if (source
!= null) {
1926 citation
= source
.getCitation();
1928 } else if (sources
.size() > 1) {
1929 logger
.warn("This Synonym has more than one source: " + syn
.getUuid() + " (" + syn
.getTitleCache() +")");
1935 /* private void xxx(List<SynonymRelationship> synonymRelationships, HashMap <UUID, ZoologicalName> zooHashMap, SynonymRelationshipType type, String addString){
1937 for (SynonymRelationship synonymRelation:synonymRelationships){
1938 TaxonNameBase synName;
1939 NonViralName inferredSynName;
1940 Synonym syn = synonymRelation.getSynonym();
1941 HibernateProxyHelper.deproxy(syn);
1943 synName = syn.getName();
1944 ZoologicalName zooName = zooHashMap.get(synName.getUuid());
1945 String synGenusName = zooName.getGenusOrUninomial();
1947 switch(type.getId()){
1948 case SynonymRelationshipType.INFERRED_EPITHET_OF().getId():
1949 inferredSynName.setSpecificEpithet(addString);
1951 case SynonymRelationshipType.INFERRED_GENUS_OF().getId():
1953 case SynonymRelationshipType.POTENTIAL_COMBINATION_OF().getId():
1957 if (!synonymsGenus.contains(synGenusName)){
1958 synonymsGenus.add(synGenusName);
1960 inferredSynName = NonViralName.NewInstance(Rank.SPECIES());
1961 inferredSynName.setSpecificEpithet(epithetOfTaxon);
1962 inferredSynName.setGenusOrUninomial(synGenusName);
1963 inferredEpithet = Synonym.NewInstance(inferredSynName, null);
1964 taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());
1965 inferredSynonyms.add(inferredEpithet);
1966 inferredSynName.generateTitle();
1967 taxonNames.add(inferredSynName.getNameCache());
1971 if (!taxonNames.isEmpty()){
1972 List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);
1973 ZoologicalName name;
1974 if (!synNotInCDM.isEmpty()){
1975 for (Synonym syn :inferredSynonyms){
1976 name =zooHashMap.get(syn.getName().getUuid());
1977 if (!synNotInCDM.contains(name.getNameCache())){
1978 inferredSynonyms.remove(syn);
1987 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countAllRelationships()
1989 public int countAllRelationships() {
1990 List
<RelationshipBase
> relationships
= this.getAllRelationships(null, 0);
1991 return relationships
.size();
1995 public List
<String
> taxaByNameNotInDB(List
<String
> taxonNames
){
1996 List
<TaxonBase
> notInDB
= new ArrayList
<TaxonBase
>();
1997 //get all taxa, already in db
1998 Query query
= getSession().createQuery("from TaxonNameBase t where t.nameCache IN (:taxonList)");
1999 query
.setParameterList("taxonList", taxonNames
);
2000 List
<TaxonNameBase
> taxaInDB
= query
.list();
2001 //compare the original list with the result of the query
2002 for (TaxonNameBase taxonName
: taxaInDB
){
2003 if (taxonName
.isInstanceOf(NonViralName
.class)) {
2004 NonViralName nonViralName
= CdmBase
.deproxy(taxonName
, NonViralName
.class);
2005 String nameCache
= nonViralName
.getNameCache();
2006 if (taxonNames
.contains(nameCache
)){
2007 taxonNames
.remove(nameCache
);
2015 //TODO: mal nur mit UUID probieren (ohne fetch all properties), vielleicht geht das schneller?
2016 public List
<UUID
> findIdenticalTaxonNameIds(List
<String
> propertyPaths
){
2017 Query query
=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
2018 List
<UUID
> zooNames
= query
.list();
2024 public List
<TaxonNameBase
> findIdenticalTaxonNames(List
<String
> propertyPaths
) {
2026 Query query
=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
2028 List
<TaxonNameBase
> zooNames
= query
.list();
2030 TaxonNameComparator taxComp
= new TaxonNameComparator();
2031 Collections
.sort(zooNames
, taxComp
);
2033 for (TaxonNameBase taxonNameBase
: zooNames
){
2034 defaultBeanInitializer
.initialize(taxonNameBase
, propertyPaths
);
2040 public List
<TaxonNameBase
> findIdenticalNamesNew(List
<String
> propertyPaths
){
2042 //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)
2043 Query query
= getSession().createQuery("Select id from Reference where titleCache like 'Fauna Europaea database'");
2044 List
<String
> secRefFauna
= query
.list();
2045 query
= getSession().createQuery("Select id from Reference where titleCache like 'ERMS'");
2046 List
<String
> secRefErms
= query
.list();
2047 //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");
2048 //Get all names of fauna europaea
2049 query
= getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefFauna");
2050 query
.setParameter("secRefFauna", secRefFauna
.get(0));
2051 List
<String
> namesFauna
= query
.list();
2053 //Get all names of erms
2055 query
= getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefErms");
2056 query
.setParameter("secRefErms", secRefErms
.get(0));
2058 List
<String
> namesErms
= query
.list();
2059 /*TaxonNameComparator comp = new TaxonNameComparator();
2060 Collections.sort(namesFauna);
2061 Collections.sort(namesErms);
2063 List
<String
> identicalNames
= new ArrayList
<String
>();
2064 String predecessor
= "";
2066 for (String nameFauna
: namesFauna
){
2067 if (namesErms
.contains(nameFauna
)){
2068 identicalNames
.add(nameFauna
);
2073 query
= getSession().createQuery("from ZoologicalName zn where zn.nameCache IN (:identicalNames)");
2074 query
.setParameterList("identicalNames", identicalNames
);
2075 List
<TaxonNameBase
> result
= query
.list();
2076 TaxonNameBase temp
= result
.get(0);
2078 Iterator
<OriginalSourceBase
> sources
= temp
.getSources().iterator();
2080 TaxonNameComparator taxComp
= new TaxonNameComparator();
2081 Collections
.sort(result
, taxComp
);
2082 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
2089 public String
getPhylumName(TaxonNameBase name
){
2090 List results
= new ArrayList();
2092 Query query
= getSession().createSQLQuery("select getPhylum("+ name
.getId()+");");
2093 results
= query
.list();
2094 }catch(Exception e
){
2095 System
.err
.println(name
.getUuid());
2098 System
.err
.println("phylum of "+ name
.getTitleCache() );
2099 return (String
)results
.get(0);
2103 public long countTaxaByCommonName(String searchString
,
2104 Classification classification
, MatchMode matchMode
,
2105 Set
<NamedArea
> namedAreas
) {
2106 boolean doCount
= true;
2107 Query query
= prepareTaxaByCommonName(searchString
, classification
, matchMode
, namedAreas
, null, null, doCount
);
2108 if (query
!= null && !query
.list().isEmpty()) {
2109 Object o
= query
.uniqueResult();
2119 public long deleteSynonymRelationships(Synonym syn
) {
2123 FROM RelTaxon AS RT INNER JOIN
2124 Taxon AS FaEuSyn ON RT.TaxonFk1 = FaEuSyn.TaxonId INNER JOIN
2125 Taxon AS ERMSAcc ON FaEuSyn.RankFk = ERMSAcc.RankFk AND FaEuSyn.FullName = ERMSAcc.FullName AND ISNULL(FaEuSyn.TaxonStatusFk, 0)
2126 <> ERMSAcc.TaxonStatusFk
2127 WHERE (FaEuSyn.OriginalDB = N'FaEu') AND (ERMSAcc.OriginalDB = N'ERMS') AND (ERMSAcc.TaxonStatusFk = 1) AND (ERMSAcc.KingdomFk = 2) AND
2128 (RT.RelTaxonQualifierFk > 100)
2130 Session session
= this.getSession();
2131 Query q
= session
.createQuery("delete SynonymRelationship sr where sr.relatedFrom = :syn");
2132 q
.setParameter("syn", syn
);
2133 return q
.executeUpdate();
2138 public Integer
countSynonymRelationships(TaxonBase taxonBase
,
2139 SynonymRelationshipType type
, Direction relatedfrom
) {
2140 AuditEvent auditEvent
= getAuditEventFromContext();
2141 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
2145 query
= getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom
+" = :relatedSynonym");
2147 query
= getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom
+" = :relatedSynonym and synonymRelationship.type = :type");
2148 query
.setParameter("type",type
);
2150 query
.setParameter("relatedTaxon", taxonBase
);
2152 return ((Long
)query
.uniqueResult()).intValue();
2154 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
2155 query
.add(AuditEntity
.relatedId(relatedfrom
.toString()).eq(taxonBase
.getId()));
2156 query
.addProjection(AuditEntity
.id().count("id"));
2159 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
2162 return ((Long
)query
.getSingleResult()).intValue();
2168 public List
<SynonymRelationship
> getSynonymRelationships(TaxonBase taxonBase
,
2169 SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
,
2170 List
<OrderHint
> orderHints
, List
<String
> propertyPaths
,
2171 Direction direction
) {
2173 AuditEvent auditEvent
= getAuditEventFromContext();
2174 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
2175 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
2177 if (direction
.equals(Direction
.relatedTo
)){
2178 criteria
.add(Restrictions
.eq("relatedTo", taxonBase
));
2180 criteria
.add(Restrictions
.eq("relatedFrom", taxonBase
));
2183 criteria
.add(Restrictions
.eq("type", type
));
2186 addOrder(criteria
,orderHints
);
2188 if(pageSize
!= null) {
2189 criteria
.setMaxResults(pageSize
);
2190 if(pageNumber
!= null) {
2191 criteria
.setFirstResult(pageNumber
* pageSize
);
2193 criteria
.setFirstResult(0);
2197 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
2198 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
2202 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
2204 if (direction
.equals(Direction
.relatedTo
)){
2205 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxonBase
.getId()));
2207 query
.add(AuditEntity
.relatedId("relatedFrom").eq(taxonBase
.getId()));
2211 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
2214 if(pageSize
!= null) {
2215 query
.setMaxResults(pageSize
);
2216 if(pageNumber
!= null) {
2217 query
.setFirstResult(pageNumber
* pageSize
);
2219 query
.setFirstResult(0);
2223 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
2224 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
2226 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
2227 // and we can't live without this functionality in CATE as it screws up the whole
2229 if(orderHints
!= null && !orderHints
.isEmpty()) {
2230 SortedSet
<SynonymRelationship
> sortedList
= new TreeSet
<SynonymRelationship
>(new SynonymRelationshipFromTaxonComparator());
2231 sortedList
.addAll(result
);
2232 return new ArrayList
<SynonymRelationship
>(sortedList
);
2241 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheTaxon()
2244 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheTaxon() {
2245 String queryString
= String
.format("select uuid, titleCache from %s where DTYPE = '%s'", type
.getSimpleName(), Taxon
.class.getSimpleName());
2246 Query query
= getSession().createQuery(queryString
);
2248 List
<UuidAndTitleCache
<TaxonBase
>> result
= getUuidAndTitleCache(query
);
2255 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheSynonym()
2258 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheSynonym() {
2259 String queryString
= String
.format("select uuid, titleCache from %s where DTYPE = '%s'", type
.getSimpleName(), Synonym
.class.getSimpleName());
2260 Query query
= getSession().createQuery(queryString
);
2262 List
<UuidAndTitleCache
<TaxonBase
>> result
= getUuidAndTitleCache(query
);