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);
}
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;
}
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);
}
}
}
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);
}
}
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;
}
}
Aggregations