Merge branch 'develop' of ssh://dev.e-taxonomy.eu/var/git/cdmlib into develop
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / NameServiceImpl.java
index 4de15a857b8b022ea5fd13f513e5d855a7736de0..8f671809852afe20582fbeedaca4e641cc8117fb 100644 (file)
@@ -11,11 +11,13 @@ package eu.etaxonomy.cdm.api.service;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.UUID;
 
@@ -35,6 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;
 import eu.etaxonomy.cdm.api.service.config.NameDeletionConfigurator;
+import eu.etaxonomy.cdm.api.service.dto.TypeDesignationStatusFilter;
 import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;
 import eu.etaxonomy.cdm.api.service.pager.Pager;
 import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl;
@@ -47,6 +50,7 @@ import eu.etaxonomy.cdm.api.service.search.LuceneSearch;
 import eu.etaxonomy.cdm.api.service.search.QueryFactory;
 import eu.etaxonomy.cdm.api.service.search.SearchResult;
 import eu.etaxonomy.cdm.api.service.search.SearchResultBuilder;
+import eu.etaxonomy.cdm.api.utility.TaxonNamePartsFilter;
 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.model.CdmBaseType;
@@ -55,6 +59,7 @@ import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.common.ReferencedEntityBase;
 import eu.etaxonomy.cdm.model.common.RelationshipBase;
 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
+import eu.etaxonomy.cdm.model.common.SourcedEntityBase;
 import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
 import eu.etaxonomy.cdm.model.name.HybridRelationship;
@@ -65,19 +70,29 @@ import eu.etaxonomy.cdm.model.name.NameRelationshipType;
 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
 import eu.etaxonomy.cdm.model.name.Rank;
+import eu.etaxonomy.cdm.model.name.Registration;
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
 import eu.etaxonomy.cdm.model.name.TaxonName;
 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
+import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
+import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
 import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
+import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
 import eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao;
-import eu.etaxonomy.cdm.persistence.dao.common.IOrderedTermVocabularyDao;
 import eu.etaxonomy.cdm.persistence.dao.common.IReferencedEntityDao;
-import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
+import eu.etaxonomy.cdm.persistence.dao.common.ISourcedEntityDao;
+import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
+import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
 import eu.etaxonomy.cdm.persistence.dao.name.IHomotypicalGroupDao;
 import eu.etaxonomy.cdm.persistence.dao.name.INomenclaturalStatusDao;
 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
 import eu.etaxonomy.cdm.persistence.dao.name.ITypeDesignationDao;
+import eu.etaxonomy.cdm.persistence.dao.term.IOrderedTermVocabularyDao;
+import eu.etaxonomy.cdm.persistence.dao.term.ITermVocabularyDao;
+import eu.etaxonomy.cdm.persistence.dto.TaxonNameParts;
 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.cdm.persistence.query.MatchMode;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
@@ -88,7 +103,9 @@ import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
 
 @Service
 @Transactional(readOnly = true)
-public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNameDao> implements INameService {
+public class NameServiceImpl
+          extends IdentifiableServiceBase<TaxonName,ITaxonNameDao>
+          implements INameService {
     static private final Logger logger = Logger.getLogger(NameServiceImpl.class);
 
     @Autowired
@@ -96,9 +113,16 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
     @Autowired
     protected IOrderedTermVocabularyDao orderedVocabularyDao;
     @Autowired
+    protected IOccurrenceService occurrenceService;
+    @Autowired
+    protected ICollectionService collectionService;
+    @Autowired
     @Qualifier("refEntDao")
     protected IReferencedEntityDao<ReferencedEntityBase> referencedEntityDao;
     @Autowired
+    @Qualifier("sourcedEntityDao")
+    protected ISourcedEntityDao<SourcedEntityBase<?>> sourcedEntityDao;
+    @Autowired
     private INomenclaturalStatusDao nomStatusDao;
     @Autowired
     private ITypeDesignationDao typeDesignationDao;
@@ -108,19 +132,17 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
     private ICdmGenericDao genericDao;
     @Autowired
     private ILuceneIndexToolProvider luceneIndexToolProvider;
+    @Autowired
+    // @Qualifier("defaultBeanInitializer")
+    protected IBeanInitializer defaultBeanInitializer;
 
     /**
      * Constructor
      */
-    public NameServiceImpl(){
-        if (logger.isDebugEnabled()) { logger.debug("Load NameService Bean"); }
-    }
+    public NameServiceImpl(){}
 
 //********************* METHODS ****************************************************************//
 
-    /* (non-Javadoc)
-     * @see eu.etaxonomy.cdm.api.service.ServiceBase#delete(eu.etaxonomy.cdm.model.common.CdmBase)
-     */
     @Override
     @Transactional(readOnly = false)
     public DeleteResult delete(UUID nameUUID){
@@ -139,7 +161,6 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
     public DeleteResult delete(TaxonName name, NameDeletionConfigurator config) {
         DeleteResult result = new DeleteResult();
 
-
         if (name == null){
             result.setAbort();
             return result;
@@ -170,10 +191,9 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
     //          throw new ReferrencedObjectUndeletableException(message);
     //      }
 
-
             try{
-            UUID nameUuid = dao.delete(name);
-
+                dao.delete(name);
+                result.addDeletedObject(name);
             }catch(Exception e){
                 result.addException(e);
                 result.setError();
@@ -184,10 +204,6 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
         return result;
     }
 
-
-    /* (non-Javadoc)
-     * @see eu.etaxonomy.cdm.api.service.INameService#delete(eu.etaxonomy.cdm.model.name.TaxonNameBase, eu.etaxonomy.cdm.api.service.NameDeletionConfigurator)
-     */
     @Override
     @Transactional(readOnly = false)
     public DeleteResult delete(UUID nameUUID, NameDeletionConfigurator config) {
@@ -197,9 +213,45 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
     }
 
     @Override
-    public DeleteResult deleteTypeDesignation(TaxonName name, TypeDesignationBase typeDesignation){
-       if(typeDesignation!=null && typeDesignation.getId()!=0){
-               typeDesignation = HibernateProxyHelper.deproxy(referencedEntityDao.load(typeDesignation.getUuid()), TypeDesignationBase.class);
+    @Transactional(readOnly = false)
+    public UpdateResult cloneTypeDesignation(UUID nameUuid, SpecimenTypeDesignation baseDesignation,
+            String accessionNumber, String barcode, String catalogNumber,
+            UUID collectionUuid, SpecimenTypeDesignationStatus typeStatus){
+        UpdateResult result = new UpdateResult();
+
+        DerivedUnit baseSpecimen = HibernateProxyHelper.deproxy(occurrenceService.load(baseDesignation.getTypeSpecimen().getUuid(), Arrays.asList("collection")), DerivedUnit.class);
+        DerivedUnit duplicate = DerivedUnit.NewInstance(baseSpecimen.getRecordBasis());
+        DerivationEvent derivedFrom = baseSpecimen.getDerivedFrom();
+        Collection<FieldUnit> fieldUnits = occurrenceService.findFieldUnits(baseSpecimen.getUuid(), null);
+        if(fieldUnits.size()!=1){
+            result.addException(new Exception("More than one or no field unit found for specimen"));
+            result.setError();
+            return result;
+        }
+        for (SpecimenOrObservationBase original : derivedFrom.getOriginals()) {
+            DerivationEvent.NewSimpleInstance(original, duplicate, derivedFrom.getType());
+        }
+        duplicate.setAccessionNumber(accessionNumber);
+        duplicate.setBarcode(barcode);
+        duplicate.setCatalogNumber(catalogNumber);
+        duplicate.setCollection(collectionService.load(collectionUuid));
+        SpecimenTypeDesignation typeDesignation = SpecimenTypeDesignation.NewInstance();
+        typeDesignation.setTypeSpecimen(duplicate);
+        typeDesignation.setTypeStatus(typeStatus);
+
+        TaxonName name = load(nameUuid);
+        name.getTypeDesignations().add(typeDesignation);
+
+        result.setCdmEntity(typeDesignation);
+        result.addUpdatedObject(name);
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public DeleteResult deleteTypeDesignation(TaxonName name, TypeDesignationBase<?> typeDesignation){
+       if(typeDesignation != null && typeDesignation .isPersited()){
+               typeDesignation = HibernateProxyHelper.deproxy(sourcedEntityDao.load(typeDesignation.getUuid()), TypeDesignationBase.class);
        }
 
         DeleteResult result = new DeleteResult();
@@ -209,27 +261,31 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
         }else if (name != null && typeDesignation != null){
             removeSingleDesignation(name, typeDesignation);
         }else if (name != null){
-            Set<TypeDesignationBase> designationSet = new HashSet<TypeDesignationBase>(name.getTypeDesignations());
-            for (Object o : designationSet){
-                TypeDesignationBase desig = CdmBase.deproxy(o, TypeDesignationBase.class);
+            @SuppressWarnings("rawtypes")
+            Set<TypeDesignationBase<?>> designationSet = new HashSet(name.getTypeDesignations());
+            for (TypeDesignationBase<?> desig : designationSet){
+                desig = CdmBase.deproxy(desig);
                 removeSingleDesignation(name, desig);
             }
         }else if (typeDesignation != null){
-            Set<TaxonName> nameSet = new HashSet<TaxonName>(typeDesignation.getTypifiedNames());
-            for (Object o : nameSet){
-                TaxonName singleName = CdmBase.deproxy(o, TaxonName.class);
+            @SuppressWarnings("unchecked")
+            Set<TaxonName> nameSet = new HashSet(typeDesignation.getTypifiedNames());
+            for (TaxonName singleName : nameSet){
+                singleName = CdmBase.deproxy(singleName);
                 removeSingleDesignation(singleName, typeDesignation);
             }
         }
+        result.addDeletedObject(typeDesignation);
         result.addUpdatedObject(name);
         return result;
     }
 
 
     @Override
+    @Transactional(readOnly = false)
     public DeleteResult deleteTypeDesignation(UUID nameUuid, UUID typeDesignationUuid){
         TaxonName nameBase = load(nameUuid);
-        TypeDesignationBase typeDesignation = HibernateProxyHelper.deproxy(referencedEntityDao.load(typeDesignationUuid), TypeDesignationBase.class);
+        TypeDesignationBase<?> typeDesignation = HibernateProxyHelper.deproxy(sourcedEntityDao.load(typeDesignationUuid), TypeDesignationBase.class);
         return deleteTypeDesignation(nameBase, typeDesignation);
     }
 
@@ -237,11 +293,22 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
      * @param name
      * @param typeDesignation
      */
-    private void removeSingleDesignation(TaxonName name, TypeDesignationBase typeDesignation) {
+    @Transactional
+    private void removeSingleDesignation(TaxonName name, TypeDesignationBase<?> typeDesignation) {
+
         name.removeTypeDesignation(typeDesignation);
         if (typeDesignation.getTypifiedNames().isEmpty()){
             typeDesignation.removeType();
+            if (!typeDesignation.getRegistrations().isEmpty()){
+                for(Object reg: typeDesignation.getRegistrations()){
+                    if (reg instanceof Registration){
+                        ((Registration)reg).removeTypeDesignation(typeDesignation);
+                    }
+                }
+            }
+
             typeDesignationDao.delete(typeDesignation);
+
         }
     }
 
@@ -251,7 +318,7 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
      * @param name
      * @param config
      */
-    private void removeNameRelationshipsByDeleteConfig(TaxonName<?,?> name, NameDeletionConfigurator config) {
+    private void removeNameRelationshipsByDeleteConfig(TaxonName name, NameDeletionConfigurator config) {
         try {
             if (config.isRemoveAllNameRelationships()){
                 Set<NameRelationship> rels = getModifiableSet(name.getNameRelations());
@@ -311,7 +378,6 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
         return result;
     }
 
-
     /**
      * TODO candidate for harmonization
      * new name saveHomotypicalGroups
@@ -320,7 +386,7 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
      */
     @Override
     public List<TaxonName> findNamesByTitleCache(String titleCache, MatchMode matchMode, List<String> propertyPaths){
-        List result = dao.findByTitle(titleCache, matchMode, null, null, null ,propertyPaths);
+        List result = dao.findByTitle(titleCache, matchMode, null, null, nullpropertyPaths);
         return result;
     }
 
@@ -332,16 +398,46 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
      */
     @Override
     public List<TaxonName> findNamesByNameCache(String nameCache, MatchMode matchMode, List<String> propertyPaths){
-        List result = dao.findByName(false, nameCache, matchMode, null, null, null ,propertyPaths);
+        List<TaxonName> result = dao.findByName(false, nameCache, matchMode, null, null, null , propertyPaths);
         return result;
     }
 
+    @Override
+    public Pager<TaxonNameParts> findTaxonNameParts(Optional<String> genusOrUninomial,
+            Optional<String> infraGenericEpithet, Optional<String> specificEpithet,
+            Optional<String> infraSpecificEpithet, Rank rank, Set<UUID> excludedNamesUuids,
+            Integer pageSize, Integer pageIndex, List<OrderHint> orderHints) {
+
+
+        long count = dao.countTaxonNameParts(genusOrUninomial, infraGenericEpithet, specificEpithet, infraGenericEpithet, rank, excludedNamesUuids);
+
+        List<TaxonNameParts> results;
+        if(AbstractPagerImpl.hasResultsInRange(count, pageIndex, pageSize)){
+            results = dao.findTaxonNameParts(genusOrUninomial, infraGenericEpithet, specificEpithet, infraSpecificEpithet,
+                    rank, excludedNamesUuids,
+                    pageSize, pageIndex, orderHints);
+        } else {
+            results = new ArrayList<>();
+        }
+
+        return new DefaultPagerImpl<TaxonNameParts>(pageIndex, count, pageSize, results);
+    }
+
     /**
-     * TODO candidate for harmonization
+     * {@inheritDoc}
      */
     @Override
-    public List getNamesByName(String name, CdmBase sessionObject){
-        return super.findCdmObjectsByTitle(name, sessionObject);
+    public Pager<TaxonNameParts> findTaxonNameParts(TaxonNamePartsFilter filter, String namePartQueryString,
+            Integer pageSize, Integer pageIndex, List<OrderHint> orderHints) {
+
+        return findTaxonNameParts(
+                filter.uninomialQueryString(namePartQueryString),
+                filter.infraGenericEpithet(namePartQueryString),
+                filter.specificEpithet(namePartQueryString),
+                filter.infraspecificEpithet(namePartQueryString),
+                filter.getRank(),
+                filter.getExludedNamesUuids(),
+                pageSize, pageIndex, orderHints);
     }
 
     /**
@@ -360,20 +456,10 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
      */
     @Override
     @Transactional(readOnly = false)
-    public Map<UUID, TypeDesignationBase> saveTypeDesignationAll(Collection<TypeDesignationBase> typeDesignationCollection){
+    public Map<UUID, TypeDesignationBase<?>> saveTypeDesignationAll(Collection<TypeDesignationBase<?>> typeDesignationCollection){
         return typeDesignationDao.saveAll(typeDesignationCollection);
     }
 
-    /**
-     * TODO candidate for harmonization
-     * new name saveReferencedEntities
-     */
-    @Override
-    @Transactional(readOnly = false)
-    public Map<UUID, ReferencedEntityBase> saveReferencedEntitiesAll(Collection<ReferencedEntityBase> referencedEntityCollection){
-        return referencedEntityDao.saveAll(referencedEntityCollection);
-    }
-
     /**
      * TODO candidate for harmonization
      * new name getNomenclaturalStatus
@@ -383,15 +469,31 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
         return nomStatusDao.list(limit, start);
     }
 
+    @Override
+    public NomenclaturalStatus loadNomenclaturalStatus(UUID uuid,  List<String> propertyPaths){
+        return nomStatusDao.load(uuid, propertyPaths);
+    }
+
     /**
      * TODO candidate for harmonization
      * new name getTypeDesignations
      */
     @Override
-    public List<TypeDesignationBase> getAllTypeDesignations(int limit, int start){
+    public List<TypeDesignationBase<?>> getAllTypeDesignations(int limit, int start){
         return typeDesignationDao.getAllTypeDesignations(limit, start);
     }
-      /**
+
+    @Override
+    public TypeDesignationBase<?> loadTypeDesignation(int id, List<String> propertyPaths){
+        return typeDesignationDao.load(id, propertyPaths);
+    }
+
+    @Override
+    public TypeDesignationBase<?> loadTypeDesignation(UUID uuid, List<String> propertyPaths){
+        return typeDesignationDao.load(uuid, propertyPaths);
+    }
+
+    /**
      * FIXME Candidate for harmonization
      * homotypicalGroupService.list
      */
@@ -737,14 +839,22 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
     @Override
     public Pager<TypeDesignationBase> getTypeDesignations(TaxonName name, SpecimenTypeDesignationStatus status,
                 Integer pageSize, Integer pageNumber, List<String> propertyPaths){
-        Integer numberOfResults = dao.countTypeDesignations(name, status);
+        long numberOfResults = dao.countTypeDesignations(name, status);
 
-        List<TypeDesignationBase> results = new ArrayList<TypeDesignationBase>();
-        if(AbstractPagerImpl.hasResultsInRange(numberOfResults.longValue(), pageNumber, pageSize)) {
+        List<TypeDesignationBase> results = new ArrayList<>();
+        if(AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)) {
             results = dao.getTypeDesignations(name, null, status, pageSize, pageNumber, propertyPaths);
         }
+        return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results);
+    }
 
-        return new DefaultPagerImpl<TypeDesignationBase>(pageNumber, numberOfResults, pageSize, results);
+    @Override
+    public List<TypeDesignationBase> getTypeDesignationsInHomotypicalGroup(UUID nameUuid, Integer pageSize,
+            Integer pageNumber, List<String> propertyPaths){
+        TaxonName name = load(nameUuid, Arrays.asList("nomenclaturalReference.authorship"));
+        Set<TypeDesignationBase<?>> typeDesignations = name.getHomotypicalGroup().getTypeDesignations();
+        List<TypeDesignationBase> result = defaultBeanInitializer.initializeAll(new ArrayList(typeDesignations), propertyPaths);
+        return result;
     }
 
     /**
@@ -754,14 +864,14 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
     @Override
     public Pager<TaxonName> searchNames(String uninomial,String infraGenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,
             List<String> propertyPaths) {
-        Integer numberOfResults = dao.countNames(uninomial, infraGenericEpithet, specificEpithet, infraspecificEpithet, rank);
+        long numberOfResults = dao.countNames(uninomial, infraGenericEpithet, specificEpithet, infraspecificEpithet, rank);
 
-        List<TaxonName> results = new ArrayList<TaxonName>();
+        List<TaxonName> results = new ArrayList<>();
         if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
             results = dao.searchNames(uninomial, infraGenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber, orderHints, propertyPaths);
         }
 
-        return new DefaultPagerImpl<TaxonName>(pageNumber, numberOfResults, pageSize, results);
+        return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results);
     }
 
     @Override
@@ -770,7 +880,8 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
     }
 
     @Override
-    public Pager<TaxonName> findByName(Class<? extends TaxonName> clazz, String queryString, MatchMode matchmode, List<Criterion> criteria, Integer pageSize,Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
+    public Pager<TaxonName> findByName(Class<TaxonName> clazz, String queryString, MatchMode matchmode, List<Criterion> criteria,
+            Integer pageSize,Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
          Long numberOfResults = dao.countByName(clazz, queryString, matchmode, criteria);
 
          List<TaxonName> results = new ArrayList<>();
@@ -788,28 +899,14 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
 
     @Override
     @Transactional(readOnly = false)
-    public void updateTitleCache(Class<? extends TaxonName> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<TaxonName> cacheStrategy, IProgressMonitor monitor) {
+    public UpdateResult updateCaches(Class<? extends TaxonName> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<TaxonName> cacheStrategy, IProgressMonitor monitor) {
         if (clazz == null){
             clazz = TaxonName.class;
         }
-        super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
+        return super.updateCachesImpl(clazz, stepSize, cacheStrategy, monitor);
     }
 
 
-    @Override
-    protected void setOtherCachesNull(TaxonName name) {
-         if (! name.isProtectedNameCache()){
-             name.setNameCache(null, false);
-        }
-        if (! name.isProtectedAuthorshipCache()){
-            name.setAuthorshipCache(null, false);
-        }
-        if (! name.isProtectedFullTitleCache()){
-            name.setFullTitleCache(null, false);
-        }
-
-    }
-
     @Override
     public List<TaggedText> getTaggedName(UUID uuid) {
         TaxonName taxonName = dao.load(uuid);
@@ -941,9 +1038,52 @@ public class NameServiceImpl extends IdentifiableServiceBase<TaxonName,ITaxonNam
 
     @Override
     public List<HashMap<String,String>> getNameRecords(){
-
                return dao.getNameRecords();
 
     }
 
+    @Override
+    public List<TypeDesignationStatusBase> getTypeDesignationStatusInUse(){
+        return typeDesignationDao.getTypeDesignationStatusInUse();
+    }
+
+    @Override
+    public Collection<TypeDesignationStatusFilter> getTypeDesignationStatusFilterTerms(List<Language> preferredLanguages){
+        List<TypeDesignationStatusBase> termList = typeDesignationDao.getTypeDesignationStatusInUse();
+        Map<String, TypeDesignationStatusFilter>  filterMap = new HashMap<>();
+        for(TypeDesignationStatusBase term : termList){
+            TypeDesignationStatusFilter filter = new TypeDesignationStatusFilter(term, preferredLanguages, true);
+            String key = filter.getKey();
+            if(filterMap.containsKey(key)){
+                filterMap.get(key).addStatus(term);
+            } else {
+                filterMap.put(key, filter);
+            }
+        }
+        return filterMap.values();
+    }
+
+    @Override
+    public <S extends TaxonName> Pager<S> page(Class<S> clazz, List<Restriction<?>> restrictions, Integer pageSize,
+            Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths) {
+        return page(clazz, restrictions, pageSize, pageIndex, orderHints, propertyPaths, INCLUDE_UNPUBLISHED);
+    }
+
+    @Override
+    public <S extends TaxonName> Pager<S> page(Class<S> clazz, List<Restriction<?>> restrictions, Integer pageSize,
+            Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths, boolean includeUnpublished) {
+
+        List<S> records;
+        long resultSize = dao.count(clazz, restrictions);
+        if(AbstractPagerImpl.hasResultsInRange(resultSize, pageIndex, pageSize)){
+            records = dao.list(clazz, restrictions, pageSize, pageIndex, orderHints, propertyPaths, includeUnpublished);
+        } else {
+            records = new ArrayList<>();
+        }
+        Pager<S> pager = new DefaultPagerImpl<>(pageIndex, resultSize, pageSize, records);
+        return pager;
+    }
+
+
+
 }