package eu.etaxonomy.cdm.persistence.dao.hibernate.taxon;\r
\r
import java.lang.reflect.Field;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.lang.reflect.Method;\r
import java.util.ArrayList;\r
import java.util.Collections;\r
+import java.util.Comparator;\r
import java.util.HashSet;\r
import java.util.Iterator;\r
import java.util.List;\r
import java.util.Set;\r
+import java.util.SortedSet;\r
+import java.util.TreeSet;\r
import java.util.UUID;\r
\r
import org.apache.log4j.Logger;\r
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
import eu.etaxonomy.cdm.model.view.AuditEvent;\r
+import eu.etaxonomy.cdm.persistence.dao.BeanInitializer;\r
import eu.etaxonomy.cdm.persistence.dao.QueryParseException;\r
import eu.etaxonomy.cdm.persistence.dao.common.ISearchableDao;\r
import eu.etaxonomy.cdm.persistence.dao.common.ITitledDao;\r
import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;\r
+import eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer;\r
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;\r
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\r
import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;\r
import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
+\r
\r
-/**\r
- * @author a.mueller\r
- *\r
- */\r
-/**\r
- * @author a.mueller\r
- * @created 24.11.2008\r
- * @version 1.0\r
- */\r
/**\r
* @author a.mueller\r
* @created 24.11.2008\r
\r
@SuppressWarnings("unused")\r
private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);\r
- \r
+ \r
private String defaultField = "name.titleCache";\r
private String defaultSort = "name.titleCache_forSort";\r
private Class<? extends TaxonBase> indexedClasses[]; \r
public List<Taxon> getRootTaxa(ReferenceBase sec) {\r
return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);\r
}\r
- \r
- @Override\r
- public TaxonBase findByUuid(UUID uuid) {\r
- TaxonBase taxonBase = super.findByUuid(uuid);\r
- if(taxonBase == null) \r
- return taxonBase;\r
\r
- Hibernate.initialize(taxonBase.getName());\r
- Hibernate.initialize(taxonBase.getSec());\r
-\r
- return taxonBase; \r
- }\r
- \r
/* (non-Javadoc)\r
* @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.ReferenceBase, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)\r
*/\r
- public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {\r
+ public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications, List<String> propertyPaths) {\r
checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");\r
if (onlyWithChildren == null){\r
onlyWithChildren = true;\r
}\r
\r
Criteria crit = getSession().createCriteria(Taxon.class);\r
- //crit.add(Restrictions.isNull("taxonomicParentCache"));\r
\r
crit.setFetchMode("name", FetchMode.JOIN);\r
crit.createAlias("name", "name");\r
\r
if (rank != null) {\r
crit.add(Restrictions.eq("name.rank", rank));\r
+ }else{\r
+ crit.add(Restrictions.isNull("taxonomicParentCache"));\r
}\r
\r
if (sec != null){\r
}\r
\r
if (! cdmFetch.includes(CdmFetch.FETCH_CHILDTAXA())){\r
- logger.warn("no child taxa fetch");\r
+ logger.info("Not fetching child taxa");\r
//TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)\r
crit.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode.LAZY);\r
}\r
List<Taxon> results = new ArrayList<Taxon>();\r
List<Taxon> taxa = crit.list();\r
for(Taxon taxon : taxa){\r
+ \r
+ \r
//childTaxa\r
//TODO create restriction instead\r
- //Hibernate.initialize(taxon.getName());\r
- Hibernate.initialize(taxon.getSec());\r
- \r
// (a) not using cache fields\r
/*Hibernate.initialize(taxon.getRelationsFromThisTaxon());\r
if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){\r
if (withMisapplications == true || ! taxon.isMisappliedName()){\r
+ defaultBeanInitializer.initialize(taxon, propertyPaths);\r
results.add(taxon);\r
}\r
}*/\r
// (b) using cache fields\r
if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){\r
if (withMisapplications == true || ! taxon.isMisappliedName()){\r
+ defaultBeanInitializer.initialize(taxon, propertyPaths);\r
results.add(taxon);\r
}\r
}\r
* @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)\r
*/\r
public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {\r
- return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications);\r
+ return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications, null);\r
}\r
\r
\r
criteria.setFetchMode( "name", FetchMode.JOIN );\r
criteria.createAlias("name", "name");\r
\r
+ if (sec != null && sec.getId() != 0) {\r
+ criteria.add(Restrictions.eq("sec", sec ) );\r
+ }\r
+\r
// FIXME: sec restriction caused problems in cich image import: results was empty\r
-// if (sec != null){\r
-// if(sec.getId() == 0){\r
-// getSession().save(sec);\r
-// }\r
-// criteria.add(Restrictions.eq("sec", sec ) );\r
-// }\r
+ \r
if (queryString != null) {\r
criteria.add(Restrictions.ilike("name.nameCache", queryString));\r
}\r
criteria.setFetchMode( "name", FetchMode.JOIN );\r
criteria.createAlias("name", "name");\r
\r
+ String hqlQueryString = matchMode.queryStringFrom(queryString);\r
if (matchMode == MatchMode.EXACT) {\r
- criteria.add(Restrictions.eq("name.nameCache", matchMode.queryStringFrom(queryString)));\r
+ criteria.add(Restrictions.eq("name.nameCache", hqlQueryString));\r
} else {\r
- criteria.add(Restrictions.ilike("name.nameCache", matchMode.queryStringFrom(queryString)));\r
+ criteria.add(Restrictions.ilike("name.nameCache", hqlQueryString));\r
}\r
- \r
-\r
-// if (queryString != null) {\r
-// criteria.add(Restrictions.ilike("name.nameCache", queryString));\r
-// }\r
-// \r
+ \r
if(pageSize != null) {\r
criteria.setMaxResults(pageSize);\r
if(pageNumber != null) {\r
List<TaxonBase> results = criteria.list();\r
return results;\r
}\r
+ \r
+ public Integer countTaxaByName(String queryString, MatchMode matchMode, \r
+ Boolean accepted) {\r
+ //TODO improve performance\r
+ List<TaxonBase> restultSet = getTaxaByName(queryString, matchMode, accepted, null, null);\r
+ return restultSet.size();\r
+ }\r
+ \r
\r
public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {\r
return super.list(pagesize, page);\r
return (List<RelationshipBase>)query.getResultList();\r
}\r
}\r
-\r
+ \r
+ /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */\r
+// private boolean nullifyTaxonomicParent(Taxon taxon) {\r
+//\r
+// try {\r
+// Method nullifyTaxonomicParent = taxon.getClass().getMethod("nullifyTaxonomicParent");\r
+// nullifyTaxonomicParent.invoke(taxon);\r
+// } catch (NoSuchMethodException ex) {\r
+// logger.error("NoSuchMethod: " + ex.getMessage());\r
+// return false;\r
+// } catch (IllegalArgumentException ex) {\r
+// logger.error("IllegalArgumentException: " + ex.getMessage());\r
+// return false;\r
+// } catch (IllegalAccessException ex) {\r
+// logger.error("IllegalAccessException: " + ex.getMessage());\r
+// return false;\r
+// } catch (InvocationTargetException ex) {\r
+// logger.error("IllegalAccessException: " + ex.getMessage());\r
+// return false;\r
+// }\r
+// return true;\r
+// }\r
+ \r
@Override\r
public UUID delete(TaxonBase taxonBase) throws DataAccessException{\r
if (taxonBase == null){\r
Taxon taxon = (Taxon)taxonBase;\r
\r
for (Iterator<TaxonRelationship> iterator = taxon.getRelationsFromThisTaxon().iterator(); iterator.hasNext();){\r
- TaxonRelationship relationToThisTaxon = iterator.next();\r
- iterator.remove();\r
- relationToThisTaxon.setFromTaxon(null);\r
- relationToThisTaxon.setToTaxon(null);\r
- getSession().delete(relationToThisTaxon);\r
- }\r
- \r
- for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){\r
TaxonRelationship relationFromThisTaxon = iterator.next();\r
iterator.remove();\r
+ \r
+ // decrease children count of taxonomic parent by one\r
+ if (relationFromThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {\r
+ Taxon toTaxon = relationFromThisTaxon.getToTaxon(); // parent\r
+ if (toTaxon != null) {\r
+ toTaxon.setTaxonomicChildrenCount(toTaxon.getTaxonomicChildrenCount() - 1); \r
+ }\r
+ }\r
relationFromThisTaxon.setToTaxon(null);\r
relationFromThisTaxon.setFromTaxon(null);\r
getSession().delete(relationFromThisTaxon);\r
}\r
\r
+ for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){\r
+ TaxonRelationship relationToThisTaxon = iterator.next();\r
+ iterator.remove();\r
+ \r
+ // set parent cache of child to null\r
+ if (relationToThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {\r
+ Taxon fromTaxon = relationToThisTaxon.getFromTaxon(); // child\r
+ if (fromTaxon != null) {\r
+ fromTaxon.nullifyTaxonomicParent();\r
+ }\r
+ }\r
+ relationToThisTaxon.setFromTaxon(null);\r
+ relationToThisTaxon.setToTaxon(null);\r
+ getSession().delete(relationToThisTaxon);\r
+ }\r
+ \r
//SynonymRelationships\r
for (Iterator<SynonymRelationship> iterator = taxon.getSynonymRelations().iterator(); iterator.hasNext();){\r
SynonymRelationship synonymRelation = iterator.next();\r
getSession().delete(taxonDescription);\r
}\r
\r
+ taxon.nullifyTaxonomicParent();\r
+\r
} else { //is Synonym\r
Synonym synonym = (Synonym)taxonBase;\r
for (Iterator<SynonymRelationship> iterator = synonym.getSynonymRelations().iterator(); iterator.hasNext();){\r
criteria.setFetchMode( "name", FetchMode.JOIN );\r
criteria.createAlias("name", "name");\r
\r
- if(genusOrUninomial != null) {\r
+ if(genusOrUninomial == null) {\r
+ criteria.add(Restrictions.isNull("name.genusOrUninomial"));\r
+ } else if(!genusOrUninomial.equals("*")) {\r
criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));\r
}\r
\r
- if(infraGenericEpithet != null) {\r
- criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));\r
- } else {\r
+ if(infraGenericEpithet == null) {\r
criteria.add(Restrictions.isNull("name.infraGenericEpithet"));\r
- }\r
+ } else if(!infraGenericEpithet.equals("*")) {\r
+ criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));\r
+ } \r
\r
- if(specificEpithet != null) {\r
+ if(specificEpithet == null) {\r
+ criteria.add(Restrictions.isNull("name.specificEpithet"));\r
+ } else if(!specificEpithet.equals("*")) {\r
criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));\r
+ \r
}\r
\r
- if(infraSpecificEpithet != null) {\r
+ if(infraSpecificEpithet == null) {\r
+ criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));\r
+ } else if(!infraSpecificEpithet.equals("*")) {\r
criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));\r
}\r
\r
return (List<TaxonBase>)criteria.list();\r
}\r
\r
- public List<TaxonRelationship> getRelatedTaxa(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber) {\r
+ public List<TaxonRelationship> getRelatedTaxa(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
AuditEvent auditEvent = getAuditEventFromContext();\r
if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
- Query query = null;\r
+ Criteria criteria = getSession().createCriteria(TaxonRelationship.class);\r
\r
- if(type == null) {\r
- query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo");\r
- } else {\r
- query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");\r
- query.setParameter("type",type);\r
- }\r
+ criteria.add(Restrictions.eq("relatedTo", taxon));\r
+ if(type != null) {\r
+ criteria.add(Restrictions.eq("type", type));\r
+ } \r
\r
- query.setParameter("relatedTo", taxon);\r
+ addOrder(criteria,orderHints);\r
\r
if(pageSize != null) {\r
- query.setMaxResults(pageSize);\r
+ criteria.setMaxResults(pageSize);\r
if(pageNumber != null) {\r
- query.setFirstResult(pageNumber * pageSize);\r
+ criteria.setFirstResult(pageNumber * pageSize);\r
} else {\r
- query.setFirstResult(0);\r
+ criteria.setFirstResult(0);\r
}\r
}\r
\r
- return (List<TaxonRelationship>)query.list();\r
+ List<TaxonRelationship> result = (List<TaxonRelationship>)criteria.list();\r
+ defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+ \r
+ return result;\r
} else {\r
AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));\r
}\r
\r
List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();\r
- for(TaxonRelationship relationship : result) {\r
- Hibernate.initialize(relationship.getFromTaxon());\r
+ defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+ \r
+ // Ugly, but for now, there is no way to sort on a related entity property in Envers,\r
+ // and we can't live without this functionality in CATE as it screws up the whole \r
+ // taxon tree thing\r
+ if(orderHints != null && !orderHints.isEmpty()) {\r
+ SortedSet<TaxonRelationship> sortedList = new TreeSet<TaxonRelationship>(new TaxonRelationshipFromTaxonComparator());\r
+ sortedList.addAll(result);\r
+ return new ArrayList<TaxonRelationship>(sortedList);\r
}\r
\r
return result;\r
}\r
}\r
+ \r
+ class TaxonRelationshipFromTaxonComparator implements Comparator<TaxonRelationship> {\r
+\r
+ public int compare(TaxonRelationship o1, TaxonRelationship o2) {\r
+ return o1.getFromTaxon().getTitleCache().compareTo(o2.getFromTaxon().getTitleCache());\r
+ }\r
+ \r
+ }\r
\r
- public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber) {\r
+ public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
AuditEvent auditEvent = getAuditEventFromContext();\r
if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
- Query query = null;\r
-\r
- if(type == null) {\r
- query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo");\r
- } else {\r
- query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");\r
- query.setParameter("type",type);\r
- }\r
-\r
- query.setParameter("relatedTo", taxon);\r
-\r
- if(pageSize != null) {\r
- query.setMaxResults(pageSize);\r
- if(pageNumber != null) {\r
- query.setFirstResult(pageNumber * pageSize);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- }\r
-\r
- return (List<SynonymRelationship>)query.list();\r
+ Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
+ \r
+ criteria.add(Restrictions.eq("relatedTo", taxon));\r
+ if(type != null) {\r
+ criteria.add(Restrictions.eq("type", type));\r
+ } \r
+ \r
+ addOrder(criteria,orderHints);\r
+ \r
+ if(pageSize != null) {\r
+ criteria.setMaxResults(pageSize);\r
+ if(pageNumber != null) {\r
+ criteria.setFirstResult(pageNumber * pageSize);\r
+ } else {\r
+ criteria.setFirstResult(0);\r
+ }\r
+ }\r
+ \r
+ List<SynonymRelationship> result = (List<SynonymRelationship>)criteria.list();\r
+ defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+ \r
+ return result;\r
} else {\r
AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());\r
query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));\r
}\r
\r
List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
- for(SynonymRelationship relationship : result) {\r
- Hibernate.initialize(relationship.getSynonym());\r
- }\r
+ defaultBeanInitializer.initializeAll(result, propertyPaths);\r
\r
return result;\r
}\r