package eu.etaxonomy.taxeditor.editor;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import eu.etaxonomy.cdm.api.service.ICommonService;
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
import eu.etaxonomy.cdm.model.name.NonViralName;
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
-import eu.etaxonomy.cdm.model.reference.StrictReferenceBase;
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
+import eu.etaxonomy.cdm.strategy.match.DefaultMatchStrategy;
+import eu.etaxonomy.cdm.strategy.match.IMatchStrategy;
import eu.etaxonomy.cdm.strategy.match.MatchException;
+import eu.etaxonomy.cdm.strategy.match.MatchMode;
import eu.etaxonomy.taxeditor.editor.name.NameComposite;
import eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor;
import eu.etaxonomy.taxeditor.store.CdmStore;
*/
private MultiPageTaxonEditor editor;
private TaxonNameEditor nameEditor;
- private Set<NameComposite<TaxonBase>> dirtyNames;
+ private Set<NameComposite<TaxonBase>> dirtyNameComposites;
- private Map<TaxonBase, ReferenceBase> duplicateReferences;
+ private List<ReferenceBase> duplicateReferences;
- private Map<TaxonBase, TaxonNameBase> duplicateNames;
+ private List<TaxonNameBase> duplicateNames;
+ private List<TeamOrPersonBase> duplicateCombinationAuthorTeams;
+ private List<TeamOrPersonBase> duplicateExCombinationAuthorTeams;
+ private List<TeamOrPersonBase> duplicateBasionymAuthorTeams;
+ private List<TeamOrPersonBase> duplicateExBasionymAuthorTeams;
+
private ICommonService commonService;
+
/**
* @param adaptableObject
*/
nameEditor = (TaxonNameEditor) editor.getPage(Page.NAME);
- duplicateReferences = new HashMap<TaxonBase, ReferenceBase>();
- duplicateNames = new HashMap<TaxonBase, TaxonNameBase>();
+ duplicateReferences = new ArrayList<ReferenceBase>();
+ duplicateNames = new ArrayList<TaxonNameBase>();
+ duplicateCombinationAuthorTeams = new ArrayList<TeamOrPersonBase>();
+ duplicateExCombinationAuthorTeams = new ArrayList<TeamOrPersonBase>();
+ duplicateBasionymAuthorTeams = new ArrayList<TeamOrPersonBase>();
+ duplicateExBasionymAuthorTeams = new ArrayList<TeamOrPersonBase>();
}
/**
// iterate over all names that were edited
for(NameComposite composite : nameEditor.getDirtyNames()){
logger.warn("Found " + composite + " with possible duplicates");
+
+ NonViralName nonViralName = (NonViralName) composite.getParsedName();
- // since we are dealing with NameComposites getData should always return a TaxonBase
- // also we do not want to handle viral names at the moment
-// NonViralName name = (NonViralName) ((TaxonBase) composite.getData()).getName();
-
- TaxonBase taxonBase = HibernateProxyHelper.deproxy(composite.getData(), TaxonBase.class);
-
- // TODO decide what entities are candidates for duplicate detection
- checkDuplicateLatinNames(taxonBase);
- checkDuplicateAuthors(taxonBase);
- checkDuplicateNomenclaturalReference(taxonBase);
+
+ duplicateNames = findMatchingLatinNames(nonViralName);
+ duplicateCombinationAuthorTeams = findMatchingAuthors((TeamOrPersonBase) nonViralName.getCombinationAuthorTeam());
+ duplicateExCombinationAuthorTeams = findMatchingAuthors((TeamOrPersonBase) nonViralName.getExCombinationAuthorTeam());
+ duplicateBasionymAuthorTeams = findMatchingAuthors((TeamOrPersonBase) nonViralName.getBasionymAuthorTeam());
+ duplicateExBasionymAuthorTeams = findMatchingAuthors((TeamOrPersonBase) nonViralName.getExBasionymAuthorTeam());
+ duplicateReferences = findMatchingNomenclaturalReference(nonViralName.getNomenclaturalReference());
+ saveNameElements(composite);
+ emptyDuplicateSets();
}
-
- solveDuplicates();
-
+ }
+
+ /**
+ *
+ */
+ private void emptyDuplicateSets() {
+ duplicateReferences.clear();
+ duplicateCombinationAuthorTeams.clear();
+ duplicateExCombinationAuthorTeams.clear();
+ duplicateBasionymAuthorTeams.clear();
+ duplicateExBasionymAuthorTeams.clear();
+ duplicateNames.clear();
}
/**
* Provides strategies to solve found duplicates
* This can either happen automatically or through user input
*/
- private void solveDuplicates() {
- /*
- * TODO first idea that comes to mind would be to present the user
- * a dialog with all possible duplicates and let her mark which entities
- * she wants to use
- *
- * If we have sophisticated equals methods that guarantee full equality and
- * there is only one match of an entity we might want to resolve the duplication
- * automatically.
+ private void saveNameElements(NameComposite composite) {
+
+ resolveDuplicateNames(composite);
+
+ resolveAllDuplicateAuthors(composite);
+
+ resolveDuplicateReferences(composite);
+
+ // FIXME this is a workaround, because title cache does not get generated correctly in library
+ // remove once #964 is closed
+ composite.getTaxon().setTitleCache((composite.getTaxon().generateTitle()));
+ }
+
+ /**
+ * @param composite
+ */
+ private void resolveDuplicateNames(NameComposite composite) {
+
+ /* When creating a new taxon editor, a taxon with an empty name is created.
+ * We have to delete this empty name explicitly from the session, otherwise it
+ * will be persisted into the database
*/
+ if(composite.getName().getFullTitleCache().length() == 0){
+ editor.getConversationHolder().delete(composite.getName());
+ }
+
+ if(duplicateNames.size() == 0){
+ // No matches were found for the name part. We can safely
+ // replace the taxons name with the parsed name
+
+ composite.setName(composite.getParsedName());
+ }else if (duplicateNames.size() == 1){
+ composite.setName(duplicateNames.iterator().next());
+ }else{
+
+ // do stuff
+ }
// debug
- for(ReferenceBase reference : duplicateReferences.values()){
- logger.warn(reference);
+ for(TaxonNameBase name : duplicateNames){
+ logger.warn(name.getFullTitleCache());
}
- for(TaxonNameBase name : duplicateNames.values()){
- logger.warn(name);
+
+ }
+
+ /**
+ * @param composite
+ */
+ private void resolveDuplicateReferences(NameComposite composite) {
+ if(duplicateReferences.size() == 0){
+ // nomatches found for the reference we replace the reference with the parsed one
+ composite.getName().setNomenclaturalReference(composite.getParsedName().getNomenclaturalReference());
+ }else if(duplicateReferences.size() == 1){
+ // exactly one match. We assume that the user wants this reference
+ composite.getName().setNomenclaturalReference(duplicateReferences.iterator().next());
+ }else{
+ // do stuff
}
+ // debug
+ for(ReferenceBase reference : duplicateReferences){
+ logger.info(reference.getTitleCache());
+ }
}
+
+
/**
- * @param name
+ * @param composite
*/
- private void checkDuplicateNomenclaturalReference(TaxonBase taxonBase) {
+ private void resolveAllDuplicateAuthors(NameComposite composite) {
+ NonViralName name = HibernateProxyHelper.deproxy(composite.getName(), NonViralName.class);
+ NonViralName parsedName = HibernateProxyHelper.deproxy(composite.getParsedName(), NonViralName.class);
- NonViralName name = getName(taxonBase);
- try{
- StrictReferenceBase referenceBase = (StrictReferenceBase) name.getNomenclaturalReference();
-
- List<StrictReferenceBase> matches = commonService.findMatching(referenceBase, null);
-
-// // query datasource for the reference
-// List<ReferenceBase> result = CdmStore.getReferenceService().getReferencesByTitle(referenceBase.getTitleCache());
-
- // if query delivers results, place possible duplicate in map
- for(ReferenceBase duplicateReference : matches){
- duplicateReferences.put(taxonBase, duplicateReference);
- }
- }catch(NullPointerException e){
- logger.warn("Name has no nomenclatural reference");
- } catch (MatchException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ if(duplicateCombinationAuthorTeams.size() == 0){
+ name.setCombinationAuthorTeam(parsedName.getCombinationAuthorTeam());
+ }else if(duplicateCombinationAuthorTeams.size() == 1){
+ name.setCombinationAuthorTeam(duplicateCombinationAuthorTeams.iterator().next());
+ }else{
+ // do stuff
+ }
+
+ if(duplicateExCombinationAuthorTeams.size() == 0){
+ name.setExCombinationAuthorTeam(parsedName.getExCombinationAuthorTeam());
+ }else if(duplicateExCombinationAuthorTeams.size() == 1){
+ name.setExCombinationAuthorTeam(duplicateExCombinationAuthorTeams.iterator().next());
+ }else{
+ // do stuff
+ }
+
+ if(duplicateBasionymAuthorTeams.size() == 0){
+ name.setBasionymAuthorTeam(parsedName.getBasionymAuthorTeam());
+ }else if(duplicateBasionymAuthorTeams.size() == 1){
+ name.setBasionymAuthorTeam(duplicateBasionymAuthorTeams.iterator().next());
+ }else{
+ // do stuff
+ }
+
+ if(duplicateExBasionymAuthorTeams.size() == 0){
+ name.setExBasionymAuthorTeam(parsedName.getExBasionymAuthorTeam());
+ }else if(duplicateExBasionymAuthorTeams.size() == 1){
+ name.setExBasionymAuthorTeam(duplicateExBasionymAuthorTeams.iterator().next());
+ }else{
+ // do stuff
}
+
+ // debug
+ for(TeamOrPersonBase authorTeam : duplicateCombinationAuthorTeams){
+ logger.info(authorTeam.getTitleCache());
+ }
+ // debug
+ for(TeamOrPersonBase authorTeam : duplicateExCombinationAuthorTeams){
+ logger.info(authorTeam.getTitleCache());
+ }
+ // debug
+ for(TeamOrPersonBase authorTeam : duplicateBasionymAuthorTeams){
+ logger.info(authorTeam.getTitleCache());
+ }
+ // debug
+ for(TeamOrPersonBase authorTeam : duplicateExBasionymAuthorTeams){
+ logger.info(authorTeam.getTitleCache());
+ }
}
+
/**
* @param name
*/
- private void checkDuplicateAuthors(TaxonBase taxonBase) {
- // see checkDuplicateNomenclaturalReference for implementation
+ private List<ReferenceBase> findMatchingNomenclaturalReference(ReferenceBase referenceBase) {
+ if(referenceBase == null) return new ArrayList<ReferenceBase>();
+ try{
+ return commonService.findMatching(referenceBase, null);
+ }catch (MatchException e) {
+ logger.error("Error finding matching references", e);
+ }
+ return null;
}
/**
* @param name
*/
- private void checkDuplicateLatinNames(TaxonBase taxonBase) {
- NonViralName name = getName(taxonBase);
-
- List<NonViralName> result = new ArrayList(); //commonService.findMatching(name, null);
+ private List<TeamOrPersonBase> findMatchingAuthors(TeamOrPersonBase authorTeam) {
+
+ if(authorTeam == null){
+ return new ArrayList<TeamOrPersonBase>();
+ }
- for(Object object: result ){
- TaxonNameBase duplicateName = HibernateProxyHelper.deproxy(object, TaxonNameBase.class);
- duplicateNames.put(taxonBase, duplicateName);
+ try{
+ return commonService.findMatching(authorTeam, null);
+ }catch (MatchException e) {
+ logger.error("Error finding matching authors", e);
}
+ return null;
}
-
+
/**
- * Helper method to get the NonViralName of a taxon base.
- *
- * @param taxonBase
- * @return
+ * @param name
*/
- private NonViralName getName(TaxonBase taxonBase){
- return HibernateProxyHelper.deproxy(taxonBase.getName(), NonViralName.class);
- }
+ private List<TaxonNameBase> findMatchingLatinNames(TaxonNameBase taxonNameBase) {
+ try {
+ IMatchStrategy strategy = DefaultMatchStrategy.NewInstance(NonViralName.class);
+ strategy.setMatchMode("nomenclaturalReference", MatchMode.IGNORE);
+ strategy.setMatchMode("combinationAuthorTeam", MatchMode.IGNORE);
+ strategy.setMatchMode("exCombinationAuthorTeam", MatchMode.IGNORE);
+ strategy.setMatchMode("basionymAuthorTeam", MatchMode.IGNORE);
+ strategy.setMatchMode("exBasionymAuthorTeam", MatchMode.IGNORE);
+
+ return commonService.findMatching(taxonNameBase, strategy);
+
+ } catch (MatchException e) {
+ logger.error("Error finding matching names", e);
+ }
+ return null;
+ }
}