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