X-Git-Url: https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blobdiff_plain/77b4a247918f406fa26f21b32f6e8cf7e1b537ab..45546a913cf144912d383d54758aa51c81367ec9:/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IdentifiableServiceBase.java diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IdentifiableServiceBase.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IdentifiableServiceBase.java index 94d9d5fceb..de1dd9fb4e 100644 --- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IdentifiableServiceBase.java +++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IdentifiableServiceBase.java @@ -1,9 +1,9 @@ // $Id$ /** * Copyright (C) 2007 EDIT -* European Distributed Institute of Taxonomy +* European Distributed Institute of Taxonomy * http://www.e-taxonomy.eu -* +* * The contents of this file are subject to the Mozilla Public License Version 1.1 * See LICENSE.TXT at the top of this package for the full license terms. */ @@ -12,32 +12,38 @@ package eu.etaxonomy.cdm.api.service; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.UUID; import org.apache.log4j.Logger; import org.hibernate.criterion.Criterion; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator; +import eu.etaxonomy.cdm.api.service.dto.FindByIdentifierDTO; import eu.etaxonomy.cdm.api.service.pager.Pager; import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl; import eu.etaxonomy.cdm.common.monitor.DefaultProgressMonitor; import eu.etaxonomy.cdm.common.monitor.IProgressMonitor; +import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; import eu.etaxonomy.cdm.model.common.CdmBase; +import eu.etaxonomy.cdm.model.common.DefinedTerm; import eu.etaxonomy.cdm.model.common.ISourceable; import eu.etaxonomy.cdm.model.common.IdentifiableEntity; import eu.etaxonomy.cdm.model.common.IdentifiableSource; import eu.etaxonomy.cdm.model.common.LSID; -import eu.etaxonomy.cdm.model.common.UuidAndTitleCache; import eu.etaxonomy.cdm.model.media.Rights; import eu.etaxonomy.cdm.model.name.NonViralName; import eu.etaxonomy.cdm.model.reference.Reference; import eu.etaxonomy.cdm.model.reference.ReferenceFactory; import eu.etaxonomy.cdm.persistence.dao.common.IIdentifiableDao; +import eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer; +import eu.etaxonomy.cdm.persistence.dao.initializer.AutoPropertyInitializer; +import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache; import eu.etaxonomy.cdm.persistence.query.MatchMode; import eu.etaxonomy.cdm.persistence.query.OrderHint; import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder; @@ -50,51 +56,51 @@ import eu.etaxonomy.cdm.strategy.merge.IMergable; import eu.etaxonomy.cdm.strategy.merge.IMergeStrategy; import eu.etaxonomy.cdm.strategy.merge.MergeException; -public abstract class IdentifiableServiceBase> extends AnnotatableServiceBase +public abstract class IdentifiableServiceBase> extends AnnotatableServiceBase implements IIdentifiableEntityService{ - - @Autowired - protected ICommonService commonService; - + protected static final int UPDATE_TITLE_CACHE_DEFAULT_STEP_SIZE = 1000; protected static final Logger logger = Logger.getLogger(IdentifiableServiceBase.class); + @Override @Transactional(readOnly = true) public Pager getRights(T t, Integer pageSize, Integer pageNumber, List propertyPaths) { Integer numberOfResults = dao.countRights(t); - + List results = new ArrayList(); if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) - results = dao.getRights(t, pageSize, pageNumber,propertyPaths); + results = dao.getRights(t, pageSize, pageNumber,propertyPaths); } - + return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); } - + + @Override @Transactional(readOnly = true) public Pager getSources(T t, Integer pageSize, Integer pageNumber, List propertyPaths) { Integer numberOfResults = dao.countSources(t); - - List results = new ArrayList(); - if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) - results = dao.getSources(t, pageSize, pageNumber,propertyPaths); - } - - return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); + + List results = new ArrayList(); + if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) + results = dao.getSources(t, pageSize, pageNumber,propertyPaths); + } + + return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); } - + @Transactional(readOnly = false) + @Override public T replace(T x, T y) { return dao.replace(x, y); } /** * FIXME Candidate for harmonization * Given that this method is strongly typed, and generic, could we not simply expose it as - * List findByTitle(String title) as it is somewhat less cumbersome. Admittedly, I don't + * List findByTitle(String title) as it is somewhat less cumbersome. Admittedly, I don't * understand what is going on with the configurators etc. so maybe there is a good reason for - * the design of this method. + * the design of this method. * @param title * @return */ @@ -102,7 +108,7 @@ public abstract class IdentifiableServiceBase findCdmObjectsByTitle(String title){ return ((IIdentifiableDao)dao).findByTitle(title); } - + @Transactional(readOnly = true) protected List findCdmObjectsByTitle(String title, Class clazz){ return ((IIdentifiableDao)dao).findByTitleAndClass(title, clazz); @@ -111,13 +117,14 @@ public abstract class IdentifiableServiceBase findCdmObjectsByTitle(String title, CdmBase sessionObject){ return ((IIdentifiableDao)dao).findByTitle(title, sessionObject); } - + /* * TODO - Migrated from CommonServiceBase * (non-Javadoc) * @see eu.etaxonomy.cdm.api.service.ICommonService#getSourcedObjectById(java.lang.String, java.lang.String) */ @Transactional(readOnly = true) + @Override public ISourceable getSourcedObjectByIdInSource(Class clazz, String idInSource, String idNamespace) { ISourceable result = null; @@ -127,104 +134,105 @@ public abstract class IdentifiableServiceBase> getUuidAndTitleCache() { return dao.getUuidAndTitleCache(); - } - - @Transactional(readOnly = true) - public Pager findByTitle(Class clazz, String queryString,MatchMode matchmode, List criteria, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { - Integer numberOfResults = dao.countByTitle(clazz, queryString, matchmode, criteria); - - List results = new ArrayList(); - if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) - results = dao.findByTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths); - } - - return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); } - + + @Transactional(readOnly = true) + @Override + public Pager findByTitle(Class clazz, String queryString,MatchMode matchmode, List criteria, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { + Integer numberOfResults = dao.countByTitle(clazz, queryString, matchmode, criteria); + + List results = new ArrayList(); + if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) + results = dao.findByTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths); + } + + return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); + } + @Transactional(readOnly = true) + @Override public Pager findByTitle(IIdentifiableEntityServiceConfigurator config){ return findByTitle(config.getClazz(), config.getTitleSearchStringSqlized(), config.getMatchMode(), config.getCriteria(), config.getPageSize(), config.getPageNumber(), config.getOrderHints(), config.getPropertyPaths()); } - + @Transactional(readOnly = true) + @Override public List listByTitle(Class clazz, String queryString,MatchMode matchmode, List criteria, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { Integer numberOfResults = dao.countByTitle(clazz, queryString, matchmode, criteria); - + List results = new ArrayList(); if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) - results = dao.findByTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths); + results = dao.findByTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths); } return results; } - + @Transactional(readOnly = true) + @Override public Pager findTitleCache(Class clazz, String queryString, Integer pageSize, Integer pageNumber, List orderHints, MatchMode matchMode){ long numberOfResults = dao.countTitleCache(clazz, queryString, matchMode); - + List results = new ArrayList(); if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) results = dao.findTitleCache(clazz, queryString, pageSize, pageNumber, orderHints, matchMode); } int r = 0; r += numberOfResults; - + return new DefaultPagerImpl(pageNumber, r , pageSize, results); } @Transactional(readOnly = true) + @Override public List listByReferenceTitle(Class clazz, String queryString,MatchMode matchmode, List criteria, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { Integer numberOfResults = dao.countByReferenceTitle(clazz, queryString, matchmode, criteria); - + List results = new ArrayList(); if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) - results = dao.findByReferenceTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths); + results = dao.findByReferenceTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths); } return results; } - + @Transactional(readOnly = true) + @Override public T find(LSID lsid) { return dao.find(lsid); } - + @Transactional(readOnly = true) + @Override public Pager search(Class clazz, String queryString, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { Integer numberOfResults = dao.count(clazz,queryString); - + List results = new ArrayList(); if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) - results = dao.search(clazz,queryString, pageSize, pageNumber, orderHints, propertyPaths); + results = dao.search(clazz,queryString, pageSize, pageNumber, orderHints, propertyPaths); } - + return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); } - - /* (non-Javadoc) - * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache() - */ @Override @Transactional(readOnly = false) public void updateTitleCache() { updateTitleCache(null, null, null, null); } - - @Transactional(readOnly = false) //TODO check transactional behaviour, e.g. what happens with the session if count is very large - protected void updateTitleCacheImpl(Class clazz, Integer stepSize, IIdentifiableEntityCacheStrategy cacheStrategy, IProgressMonitor monitor) { + + @Transactional(readOnly = false) //TODO check transactional behaviour, e.g. what happens with the session if count is very large + protected void updateTitleCacheImpl(Class clazz, Integer stepSize, IIdentifiableEntityCacheStrategy cacheStrategy, IProgressMonitor monitor) { if (stepSize == null){ stepSize = UPDATE_TITLE_CACHE_DEFAULT_STEP_SIZE; } if (monitor == null){ monitor = DefaultProgressMonitor.NewInstance(); } - + int count = dao.count(clazz); monitor.beginTask("update titles", count); int worked = 0; @@ -232,9 +240,15 @@ public abstract class IdentifiableServiceBase orderHints = new ArrayList(); orderHints.add( new OrderHint("id", OrderHint.SortOrder.ASCENDING)); - List list = this.list(clazz, stepSize, i, orderHints, null); + + + Map, AutoPropertyInitializer> oldAutoInit = switchOfAutoinitializer(); + List list = this.list(clazz, stepSize, i, orderHints, null); + switchOnOldAutoInitializer(oldAutoInit); + List entitiesToUpdate = new ArrayList(); for (T entity : list){ + HibernateProxyHelper.deproxy(entity, clazz); if (entity.isProtectedTitleCache() == false){ updateTitleCacheForSingleEntity(cacheStrategy, entitiesToUpdate, entity); } @@ -257,6 +271,31 @@ public abstract class IdentifiableServiceBase, AutoPropertyInitializer> oldAutoInit) { + HibernateBeanInitializer initializer = (HibernateBeanInitializer)this.appContext.getBean("defaultBeanInitializer"); + initializer.setBeanAutoInitializers(oldAutoInit); + } + + /** + * Removes all auto initializers from the bean initializer + * + * @see #switchOnOldAutoInitializer(Map) + * @return + */ + protected Map, AutoPropertyInitializer> switchOfAutoinitializer() { + HibernateBeanInitializer initializer = (HibernateBeanInitializer)this.appContext.getBean("defaultBeanInitializer"); + Map, AutoPropertyInitializer> oldAutoInitializers = initializer.getBeanAutoInitializers(); + Map, AutoPropertyInitializer> map = new HashMap, AutoPropertyInitializer>(); + initializer.setBeanAutoInitializers(map); + return oldAutoInitializers; + } + /** * @param cacheStrategy * @param entitiesToUpdate @@ -267,12 +306,13 @@ public abstract class IdentifiableServiceBase cacheStrategy, List entitiesToUpdate, T entity) { - - assert (entity.isProtectedTitleCache() == false ); - + + //assert (entity.isProtectedTitleCache() == false ); + //exclude recursive inreferences if (entity.isInstanceOf(Reference.class)){ Reference ref = CdmBase.deproxy(entity, Reference.class); @@ -280,66 +320,113 @@ public abstract class IdentifiableServiceBase)entity).getType()).getCacheStrategy(); } } - entity.setCacheStrategy(entityCacheStrategy); - + + //old titleCache entity.setProtectedTitleCache(true); - String oldTitleCache = entity.getTitleCache(); - entity.setProtectedTitleCache(false); - //NonViralNames have more caches //TODO handle in NameService + String oldTitleCache = entity.getTitleCache(); + entity.setTitleCache(oldTitleCache, false); //before we had entity.setProtectedTitleCache(false) but this deleted the titleCache itself + entity.setCacheStrategy(entityCacheStrategy); + //NonViralNames and Reference have more caches //TODO handle in NameService String oldNameCache = null; String oldFullTitleCache = null; + String oldAbbrevTitleCache = null; if (entity instanceof NonViralName ){ - NonViralName nvn = (NonViralName) entity; - if (!nvn.isProtectedNameCache()){ - nvn.setProtectedNameCache(true); - oldNameCache = nvn.getNameCache(); - nvn.setProtectedNameCache(false); + + try{ + NonViralName nvn = (NonViralName) entity; + if (!nvn.isProtectedNameCache()){ + nvn.setProtectedNameCache(true); + oldNameCache = nvn.getNameCache(); + nvn.setProtectedNameCache(false); + } + if (!nvn.isProtectedFullTitleCache()){ + nvn.setProtectedFullTitleCache(true); + oldFullTitleCache = nvn.getFullTitleCache(); + nvn.setProtectedFullTitleCache(false); + } + }catch(ClassCastException e){ + System.out.println("entity: " + entity.getTitleCache()); } - if (!nvn.isProtectedFullTitleCache()){ - nvn.setProtectedFullTitleCache(true); - oldFullTitleCache = nvn.getFullTitleCache(); - nvn.setProtectedFullTitleCache(false); + + }else if (entity instanceof Reference){ + Reference ref = (Reference) entity; + if (!ref.isProtectedAbbrevTitleCache()){ + ref.setProtectedAbbrevTitleCache(true); + oldAbbrevTitleCache = ref.getAbbrevTitleCache(); + ref.setProtectedAbbrevTitleCache(false); } } - setOtherCachesNull(entity); //TODO find better solution - - String newTitleCache = entityCacheStrategy.getTitleCache(entity); - if (oldTitleCache == null || oldTitleCache != null && ! oldTitleCache.equals(newTitleCache) ){ - entity.setTitleCache(null, false); - entity.getTitleCache(); + setOtherCachesNull(entity); + String newTitleCache= null; + NonViralName nvn = null;//TODO find better solution + try{ if (entity instanceof NonViralName){ - NonViralName nvn = (NonViralName) entity; + nvn = (NonViralName) entity; + newTitleCache = entityCacheStrategy.getTitleCache(nvn); + } else{ + newTitleCache = entityCacheStrategy.getTitleCache(entity); + } + }catch (ClassCastException e){ + nvn = HibernateProxyHelper.deproxy(entity, NonViralName.class); + newTitleCache = entityCacheStrategy.getTitleCache(nvn); + //System.out.println("titleCache: " +entity.getTitleCache()); + } + + if ( oldTitleCache == null || oldTitleCache != null && ! oldTitleCache.equals(newTitleCache) ){ + entity.setTitleCache(null, false); + String newCache = entity.getTitleCache(); + + if (newCache == null){ + logger.warn("newCache should never be null"); + } + if (oldTitleCache == null){ + logger.info("oldTitleCache should never be null"); + } + if (nvn != null){ + //NonViralName nvn = (NonViralName) entity; nvn.getNameCache(); nvn.getFullTitleCache(); } + if (entity instanceof Reference){ + Reference ref = (Reference) entity; + ref.getAbbrevTitleCache(); + } entitiesToUpdate.add(entity); - }else if (entity instanceof NonViralName){ - NonViralName nvn = (NonViralName) entity; - String newnameCache = nvn.getNameCache(); + }else if (nvn != null){ + //NonViralName nvn = (NonViralName) entity; + String newNameCache = nvn.getNameCache(); String newFullTitleCache = nvn.getFullTitleCache(); - if (oldNameCache == null || (oldNameCache != null && !oldNameCache.equals(newnameCache))){ + if ((oldNameCache == null && !nvn.isProtectedNameCache()) || (oldNameCache != null && !oldNameCache.equals(newNameCache))){ entitiesToUpdate.add(entity); - }else if (oldFullTitleCache == null || (oldFullTitleCache != null && !oldFullTitleCache.equals(newFullTitleCache))){ + }else if ((oldFullTitleCache == null && !nvn.isProtectedFullTitleCache()) || (oldFullTitleCache != null && !oldFullTitleCache.equals(newFullTitleCache))){ + entitiesToUpdate.add(entity); + } + }else if (entity instanceof Reference){ + Reference ref = (Reference) entity; + String newAbbrevTitleCache = ref.getAbbrevTitleCache(); + if ( (oldAbbrevTitleCache == null && !ref.isProtectedAbbrevTitleCache() ) || (oldAbbrevTitleCache != null && !oldAbbrevTitleCache.equals(newAbbrevTitleCache))){ entitiesToUpdate.add(entity); } } + + } - - + + /** * Needs override if not only the title cache should be set to null to @@ -348,26 +435,23 @@ public abstract class IdentifiableServiceBase clazz, IMatchStrategy matchStrategy, IMergeStrategy mergeStrategy) { DeduplicateState dedupState = new DeduplicateState(); - + if (clazz == null){ logger.warn("Deduplication clazz must not be null!"); return 0; @@ -381,16 +465,16 @@ public abstract class IdentifiableServiceBase nextGroup = new ArrayList(); - + int result = 0; // double countTotal = count(clazz); -// -// Number countPagesN = Math.ceil(countTotal/dedupState.pageSize.doubleValue()) ; +// +// Number countPagesN = Math.ceil(countTotal/dedupState.pageSize.doubleValue()) ; // int countPages = countPagesN.intValue(); -// - +// + List orderHints = Arrays.asList(new OrderHint[]{new OrderHint("titleCache", SortOrder.ASCENDING)}); - + while (! dedupState.isCompleted){ //get x page sizes List objectList = getPages(clazz, dedupState, orderHints); @@ -401,7 +485,7 @@ public abstract class IdentifiableServiceBase(); nextGroup.add(object); - nUnEqual++; + nUnEqual++; } dedupState.lastTitleCache = currentTitleCache; } @@ -453,7 +537,7 @@ public abstract class IdentifiableServiceBase clazz, String queryString,MatchMode matchmode, List criteria){ + } + + @Transactional(readOnly = true) + @Override + public Integer countByTitle(Class clazz, String queryString,MatchMode matchmode, List criteria){ Integer numberOfResults = dao.countByTitle(clazz, queryString, matchmode, criteria); - + return numberOfResults; - } - + } + @Transactional(readOnly = true) + @Override public Integer countByTitle(IIdentifiableEntityServiceConfigurator config){ return countByTitle(config.getClazz(), config.getTitleSearchStringSqlized(), config.getMatchMode(), config.getCriteria()); - + + } + + @Override + @Transactional(readOnly = true) + public Pager> findByIdentifier( + Class clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode, + boolean includeEntity, Integer pageSize, + Integer pageNumber, List propertyPaths) { + + Integer numberOfResults = dao.countByIdentifier(clazz, identifier, identifierType, matchmode); + List daoResults = new ArrayList(); + if(numberOfResults > 0) { // no point checking again + daoResults = dao.findByIdentifier(clazz, identifier, identifierType, + matchmode, includeEntity, pageSize, pageNumber, propertyPaths); + } + + List> result = new ArrayList>(); + for (Object[] daoObj : daoResults){ + if (includeEntity){ + result.add(new FindByIdentifierDTO((DefinedTerm)daoObj[0], (String)daoObj[1], (S)daoObj[2])); + }else{ + result.add(new FindByIdentifierDTO((DefinedTerm)daoObj[0], (String)daoObj[1], (UUID)daoObj[2], (String)daoObj[3])); + } + } + return new DefaultPagerImpl>(pageNumber, numberOfResults, pageSize, result); } -} + +}