fixes #888 and #889
[taxeditor.git] / taxeditor-editor / src / main / java / eu / etaxonomy / taxeditor / editor / DuplicateArbitrator.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.taxeditor.editor;
11
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17
18 import org.apache.log4j.Logger;
19
20 import eu.etaxonomy.cdm.api.service.ICommonService;
21 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
22 import eu.etaxonomy.cdm.model.name.NonViralName;
23 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
24 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
25 import eu.etaxonomy.cdm.model.reference.StrictReferenceBase;
26 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
27 import eu.etaxonomy.cdm.strategy.match.MatchException;
28 import eu.etaxonomy.taxeditor.editor.name.NameComposite;
29 import eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor;
30 import eu.etaxonomy.taxeditor.store.CdmStore;
31
32 /**
33 * This class is supposed to handle possible duplications of cdm entities
34 * for a specific editor
35 *
36 * TODO break dependency to editor
37 *
38 * @author n.hoffmann
39 * @created 03.07.2009
40 * @version 1.0
41 *
42 */
43 public class DuplicateArbitrator {
44 private static final Logger logger = Logger.getLogger(DuplicateArbitrator.class);
45
46 /**
47 * The editor this arbitrator should manage possible duplicates for
48 */
49 private MultiPageTaxonEditor editor;
50 private TaxonNameEditor nameEditor;
51 private Set<NameComposite<TaxonBase>> dirtyNames;
52
53 private Map<TaxonBase, ReferenceBase> duplicateReferences;
54
55 private Map<TaxonBase, TaxonNameBase> duplicateNames;
56
57 private ICommonService commonService;
58
59 /**
60 * @param adaptableObject
61 */
62 public DuplicateArbitrator(MultiPageTaxonEditor editor) {
63 this.editor = editor;
64
65 commonService = CdmStore.getCommonService();
66
67 nameEditor = (TaxonNameEditor) editor.getPage(Page.NAME);
68
69 duplicateReferences = new HashMap<TaxonBase, ReferenceBase>();
70 duplicateNames = new HashMap<TaxonBase, TaxonNameBase>();
71 }
72
73 /**
74 * Provide strategies on how to handle possible duplications
75 */
76 public void arbitrate() {
77 // iterate over all names that were edited
78 for(NameComposite composite : nameEditor.getDirtyNames()){
79 logger.warn("Found " + composite + " with possible duplicates");
80
81 // since we are dealing with NameComposites getData should always return a TaxonBase
82 // also we do not want to handle viral names at the moment
83 // NonViralName name = (NonViralName) ((TaxonBase) composite.getData()).getName();
84
85 TaxonBase taxonBase = HibernateProxyHelper.deproxy(composite.getData(), TaxonBase.class);
86
87 // TODO decide what entities are candidates for duplicate detection
88 checkDuplicateLatinNames(taxonBase);
89 checkDuplicateAuthors(taxonBase);
90 checkDuplicateNomenclaturalReference(taxonBase);
91
92
93 }
94
95 solveDuplicates();
96
97 }
98
99 /**
100 * Provides strategies to solve found duplicates
101 * This can either happen automatically or through user input
102 */
103 private void solveDuplicates() {
104 /*
105 * TODO first idea that comes to mind would be to present the user
106 * a dialog with all possible duplicates and let her mark which entities
107 * she wants to use
108 *
109 * If we have sophisticated equals methods that guarantee full equality and
110 * there is only one match of an entity we might want to resolve the duplication
111 * automatically.
112 */
113
114 // debug
115 for(ReferenceBase reference : duplicateReferences.values()){
116 logger.warn(reference);
117 }
118 for(TaxonNameBase name : duplicateNames.values()){
119 logger.warn(name);
120 }
121
122 }
123
124 /**
125 * @param name
126 */
127 private void checkDuplicateNomenclaturalReference(TaxonBase taxonBase) {
128
129 NonViralName name = getName(taxonBase);
130
131 try{
132 StrictReferenceBase referenceBase = (StrictReferenceBase) name.getNomenclaturalReference();
133
134 List<StrictReferenceBase> matches = commonService.findMatching(referenceBase, null);
135
136 // // query datasource for the reference
137 // List<ReferenceBase> result = CdmStore.getReferenceService().getReferencesByTitle(referenceBase.getTitleCache());
138
139 // if query delivers results, place possible duplicate in map
140 for(ReferenceBase duplicateReference : matches){
141 duplicateReferences.put(taxonBase, duplicateReference);
142 }
143 }catch(NullPointerException e){
144 logger.warn("Name has no nomenclatural reference");
145 } catch (MatchException e) {
146 // TODO Auto-generated catch block
147 e.printStackTrace();
148 }
149
150 }
151
152 /**
153 * @param name
154 */
155 private void checkDuplicateAuthors(TaxonBase taxonBase) {
156 // see checkDuplicateNomenclaturalReference for implementation
157 }
158
159 /**
160 * @param name
161 */
162 private void checkDuplicateLatinNames(TaxonBase taxonBase) {
163 NonViralName name = getName(taxonBase);
164
165 List<NonViralName> result = new ArrayList(); //commonService.findMatching(name, null);
166
167 for(Object object: result ){
168 TaxonNameBase duplicateName = HibernateProxyHelper.deproxy(object, TaxonNameBase.class);
169 duplicateNames.put(taxonBase, duplicateName);
170 }
171 }
172
173 /**
174 * Helper method to get the NonViralName of a taxon base.
175 *
176 * @param taxonBase
177 * @return
178 */
179 private NonViralName getName(TaxonBase taxonBase){
180 return HibernateProxyHelper.deproxy(taxonBase.getName(), NonViralName.class);
181 }
182
183 }