Search in sources :

Example 1 with MergeException

use of eu.etaxonomy.cdm.strategy.merge.MergeException in project cdmlib by cybertaxonomy.

the class CommonServiceImpl method merge.

@Override
@Transactional(readOnly = false)
public <T extends IMergable> void merge(UUID mergeFirstUuid, UUID mergeSecondUuid, Class<? extends CdmBase> clazz) throws MergeException {
    IMergeStrategy mergeStrategy;
    T mergeFirst = (T) genericDao.find(clazz, mergeFirstUuid);
    T mergeSecond = (T) genericDao.find(clazz, mergeSecondUuid);
    if (mergeFirst == null) {
        throw new MergeException("The merge target is not available anymore.");
    }
    if (mergeSecond == null) {
        throw new MergeException("The merge candidate is not available anymore.");
    }
    mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);
    merge(mergeFirst, mergeSecond, mergeStrategy);
}
Also used : MergeException(eu.etaxonomy.cdm.strategy.merge.MergeException) IMergeStrategy(eu.etaxonomy.cdm.strategy.merge.IMergeStrategy) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with MergeException

use of eu.etaxonomy.cdm.strategy.merge.MergeException in project cdmlib by cybertaxonomy.

the class AgentServiceImpl method convertPerson2Team.

@Override
public UpdateResult convertPerson2Team(Person person) throws MergeException, IllegalArgumentException {
    if (person == null) {
        throw new IllegalArgumentException("Person does not exist.");
    }
    UpdateResult result = new UpdateResult();
    Team team = Team.NewInstance();
    ConvertMergeStrategy strategy = ConvertMergeStrategy.NewInstance(TeamOrPersonBase.class);
    strategy.setDefaultMergeMode(MergeMode.SECOND);
    strategy.setDefaultCollectionMergeMode(MergeMode.SECOND);
    if (person.isProtectedTitleCache() || !person.getTitleCache().startsWith("Person#")) {
        // the later is for checking if the person is empty, this can be done better
        // as there are no members we set the titleCache to protected (as long as titleCache does not take the protected nomenclatural title but results in '-empty team-' in this situation); for some reason it is necessary to also set the title cache as well here, otherwise it is recomputed during the merge
        team.setTitleCache(person.getTitleCache(), true);
    }
    // as we do not add team members, the titleCache of the new team should be always protected
    strategy.setMergeMode("protectedTitleCache", MergeMode.FIRST);
    strategy.setDeleteSecondObject(true);
    if (StringUtils.isNotBlank(person.getNomenclaturalTitle())) {
        // sets the protected flag always to true, this is necessary as long as person does not have a nomenclatural title cache; maybe setting the protected title itself is not necessary but does no harm
        team.setNomenclaturalTitleCache(person.getNomenclaturalTitle(), true);
    }
    if (StringUtils.isNotBlank(person.getCollectorTitle())) {
        // sets the protected flag always to true, this is necessary as long as person does not have a collector title cache; maybe setting the protected title itself is not necessary but does no harm
        team.setCollectorTitleCache(person.getCollectorTitle(), true);
    }
    if (!genericDao.isMergeable(team, person, strategy)) {
        throw new MergeException("Person can not be transformed into team.");
    }
    try {
        team = this.save(team);
        genericDao.merge(team, person, strategy);
    // Note: we decided  never add the old person as (first) member of the team as there are not many usecases for this.
    // But we may try to parse the old person into members which may handle the case that teams have been stored as unparsed persons
    } catch (Exception e) {
        throw new MergeException("Unhandled merge exception", e);
    }
    result.setCdmEntity(team);
    result.addUpdatedObject(team);
    return result;
}
Also used : MergeException(eu.etaxonomy.cdm.strategy.merge.MergeException) Team(eu.etaxonomy.cdm.model.agent.Team) ConvertMergeStrategy(eu.etaxonomy.cdm.strategy.merge.ConvertMergeStrategy) MergeException(eu.etaxonomy.cdm.strategy.merge.MergeException)

Example 3 with MergeException

use of eu.etaxonomy.cdm.strategy.merge.MergeException in project cdmlib by cybertaxonomy.

the class DeduplicationHelper method reallocateCollection.

private void reallocateCollection(CdmBase cdmBase1, CdmBase cdmBase2, ReferenceHolder refHolder, Set<ICdmBase> cloneSet) throws MergeException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    List<CdmBase> list = genericDao.getCdmBasesWithItemInCollection(refHolder.itemClass, refHolder.otherClass, refHolder.propertyName, cdmBase2, null);
    for (CdmBase referencingObject : list) {
        Field referencingField = getFieldRecursive(refHolder.otherClass, refHolder.propertyName);
        referencingField.setAccessible(true);
        Object collection = referencingField.get(referencingObject);
        if (!(collection instanceof Collection)) {
            throw new MergeException("Reallocation of collections for collection other than set and list not yet implemented");
        } else if (collection instanceof List) {
            Method replaceMethod = DefaultMergeStrategy.getReplaceMethod(referencingField);
            replaceMethod.invoke(referencingObject, cdmBase1, cdmBase2);
        } else {
            Method addMethod = DefaultMergeStrategy.getAddMethod(referencingField, false);
            Method removeMethod = DefaultMergeStrategy.getAddMethod(referencingField, true);
            addMethod.invoke(referencingObject, cdmBase1);
            removeMethod.invoke(referencingObject, cdmBase2);
        }
    }
}
Also used : Field(java.lang.reflect.Field) MergeException(eu.etaxonomy.cdm.strategy.merge.MergeException) ICdmBase(eu.etaxonomy.cdm.model.common.ICdmBase) CdmBase(eu.etaxonomy.cdm.model.common.CdmBase) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List) Method(java.lang.reflect.Method)

Example 4 with MergeException

use of eu.etaxonomy.cdm.strategy.merge.MergeException in project cdmlib by cybertaxonomy.

the class DeduplicationHelper method merge.

public <T extends CdmBase> void merge(T cdmBase1, T cdmBase2, IMergeStrategy mergeStrategy) throws MergeException {
    @SuppressWarnings("unchecked") Class<T> clazz = (Class<T>) cdmBase1.getClass();
    @SuppressWarnings("unchecked") Class<T> clazz2 = (Class<T>) cdmBase2.getClass();
    if (mergeStrategy == null) {
        mergeStrategy = DefaultMergeStrategy.NewInstance(cdmBase1.getClass());
    }
    try {
        // check null and types
        checkMergeValid(cdmBase1, cdmBase2, mergeStrategy);
        // merge objects
        // externel impl
        // internal impl
        Set<ICdmBase> deleteSet = new HashSet<>();
        Set<ICdmBase> cloneSet = new HashSet<>();
        if (cdmBase1 instanceof IMergable) {
            IMergable mergable1 = (IMergable) cdmBase1;
            IMergable mergable2 = (IMergable) cdmBase2;
            deleteSet = mergeStrategy.invoke(mergable1, mergable2, cloneSet);
        // session.saveOrUpdate(mergable1);
        // session.flush();
        // ((IMergable)cdmBase1).mergeInto(cdmBase2, DefaultMergeStrategy.NewInstance(cdmBase1.getClass()));
        } else {
            // TODO should we better use clazz2 here?
            mergeExternal(cdmBase1, cdmBase2, clazz, session);
        }
        if (cdmBase2.getId() > 0) {
            session.saveOrUpdate(cdmBase2);
            session.flush();
            // rearrange references pointing to cdmBase2 to cdmBase1 in future
            reallocateReferences(cdmBase1, cdmBase2, clazz2, cloneSet);
        }
        // remove deleted objects
        // session.delete(null, mergable2, true, null);
        boolean deleteSecond = true;
        if (mergeStrategy instanceof ConvertMergeStrategy) {
            deleteSecond = ((ConvertMergeStrategy) mergeStrategy).isDeleteSecondObject();
        }
        if (deleteSecond) {
            session.delete(cdmBase2);
            for (ICdmBase toBeDeleted : deleteSet) {
                logger.debug("Delete " + toBeDeleted);
                if (toBeDeleted != cdmBase2) {
                    session.delete(toBeDeleted);
                }
            }
        }
        // flush
        session.flush();
    } catch (Exception e) {
        e.printStackTrace();
        throw new MergeException(e);
    }
}
Also used : IMergable(eu.etaxonomy.cdm.strategy.merge.IMergable) MergeException(eu.etaxonomy.cdm.strategy.merge.MergeException) ConvertMergeStrategy(eu.etaxonomy.cdm.strategy.merge.ConvertMergeStrategy) UnhandledException(org.apache.commons.lang.UnhandledException) MergeException(eu.etaxonomy.cdm.strategy.merge.MergeException) InvocationTargetException(java.lang.reflect.InvocationTargetException) MappingException(org.hibernate.MappingException) ICdmBase(eu.etaxonomy.cdm.model.common.ICdmBase) HashSet(java.util.HashSet)

Example 5 with MergeException

use of eu.etaxonomy.cdm.strategy.merge.MergeException in project cdmlib by cybertaxonomy.

the class DeduplicationHelper method checkInstancesMergeable.

@SuppressWarnings("unchecked")
private <T extends CdmBase> boolean checkInstancesMergeable(T cdmBase1, T cdmBase2, IMergeStrategy strategy) {
    Class<T> clazz2 = (Class<T>) cdmBase2.getClass();
    // FIXME do we need to compute the cloneSet? See #reallocateReferences for comparison
    // this is only a copy from there. Maybe we do not need the cloneSet at all here
    Set<ICdmBase> cloneSet = new HashSet<>();
    Set<ReferenceHolder> holderSet;
    try {
        boolean result = true;
        holderSet = genericDao.getOrMakeHolderSet(clazz2);
        for (ReferenceHolder refHolder : holderSet) {
            if (!reallocateByHolderPossible(cdmBase1, cdmBase2, refHolder, cloneSet)) {
                return false;
            }
        }
        return result;
    } catch (ClassNotFoundException | NoSuchFieldException | MergeException e) {
        return false;
    }
}
Also used : ICdmBase(eu.etaxonomy.cdm.model.common.ICdmBase) MergeException(eu.etaxonomy.cdm.strategy.merge.MergeException) ReferenceHolder(eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl.ReferenceHolder) HashSet(java.util.HashSet)

Aggregations

MergeException (eu.etaxonomy.cdm.strategy.merge.MergeException)14 Team (eu.etaxonomy.cdm.model.agent.Team)5 TaxonName (eu.etaxonomy.cdm.model.name.TaxonName)5 CdmTransactionalIntegrationTest (eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest)5 Test (org.junit.Test)5 Person (eu.etaxonomy.cdm.model.agent.Person)4 Annotation (eu.etaxonomy.cdm.model.common.Annotation)4 HashSet (java.util.HashSet)4 DataSets (org.unitils.dbunit.annotation.DataSets)4 ICdmBase (eu.etaxonomy.cdm.model.common.ICdmBase)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)3 UnhandledException (org.apache.commons.lang.UnhandledException)3 MappingException (org.hibernate.MappingException)3 IntextReference (eu.etaxonomy.cdm.model.common.IntextReference)2 MatchException (eu.etaxonomy.cdm.strategy.match.MatchException)2 ConvertMergeStrategy (eu.etaxonomy.cdm.strategy.merge.ConvertMergeStrategy)2 Field (java.lang.reflect.Field)2 CollectionMetadata (org.hibernate.metadata.CollectionMetadata)2 AnyType (org.hibernate.type.AnyType)2 CollectionType (org.hibernate.type.CollectionType)2