cleanup
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / specimen / SpecimenUserInteraction.java
1 /**
2 * Copyright (C) 2013 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 package eu.etaxonomy.cdm.io.specimen;
10
11 import java.awt.Color;
12 import java.awt.Dimension;
13 import java.awt.event.ItemEvent;
14 import java.awt.event.ItemListener;
15 import java.io.Serializable;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.UUID;
24
25 import javax.swing.BoxLayout;
26 import javax.swing.ButtonGroup;
27 import javax.swing.JLabel;
28 import javax.swing.JOptionPane;
29 import javax.swing.JPanel;
30 import javax.swing.JRadioButton;
31 import javax.swing.JScrollPane;
32 import javax.swing.JTextArea;
33
34 import org.apache.commons.lang.StringUtils;
35 import org.apache.logging.log4j.LogManager;
36 import org.apache.logging.log4j.Logger;
37
38 import eu.etaxonomy.cdm.api.service.IReferenceService;
39 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
40 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
41 import eu.etaxonomy.cdm.model.description.TaxonDescription;
42 import eu.etaxonomy.cdm.model.reference.OriginalSourceBase;
43 import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
44 import eu.etaxonomy.cdm.model.reference.Reference;
45 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
46 import eu.etaxonomy.cdm.model.taxon.Classification;
47 import eu.etaxonomy.cdm.model.taxon.Taxon;
48 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
49 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
50
51 /**
52 * @author pkelbert
53 * @since 21 juin 2013
54 */
55 public class SpecimenUserInteraction implements ItemListener, Serializable {
56
57 private static final long serialVersionUID = 6384263183459028523L;
58 @SuppressWarnings("unused")
59 private static final Logger log = LogManager.getLogger();
60
61 public Classification askForClassification(Map<String, Classification> classMap){
62 List<String> possibilities = new ArrayList<String>(classMap.keySet());
63 Collections.sort(possibilities);
64
65 if (classMap.keySet().size()>0) {
66 classMap.put("Nothing matches, create a new classification",null);
67 possibilities.add(0, "Nothing matches, create a new classification");
68 } else {
69 return null;
70 }
71
72 JTextArea textArea = new JTextArea("Which existing classification should be used ?");
73 JScrollPane scrollPane = new JScrollPane(textArea);
74 textArea.setLineWrap(true);
75 textArea.setWrapStyleWord(true);
76 scrollPane.setPreferredSize( new Dimension( 500, 50 ) );
77
78 String s = null;
79 while (s == null) {
80 s= (String)JOptionPane.showInputDialog(
81 null,
82 scrollPane,
83 "Please select a classification in the list",
84 JOptionPane.PLAIN_MESSAGE,
85 null,
86 possibilities.toArray(),
87 "Nothing matches, create a new classification");
88 }
89 return classMap.get(s);
90 }
91
92 /**
93 * @return the name for the new Classification
94 */
95 public String createNewClassification() {
96 JTextArea textArea = new JTextArea("How should the classification be named ?");
97 JScrollPane scrollPane = new JScrollPane(textArea);
98 textArea.setLineWrap(true);
99 textArea.setWrapStyleWord(true);
100 scrollPane.setPreferredSize( new Dimension( 500, 50 ) );
101
102 String s = null;
103 while (s == null) {
104 s=(String)JOptionPane.showInputDialog(
105 null,
106 scrollPane,
107 "Get full classification name",
108 JOptionPane.PLAIN_MESSAGE,
109 null,
110 null,
111 "ABCD Import");
112 }
113 return s;
114 }
115
116 /**
117 * @param refMap
118 * @return
119 */
120 public Reference askForReference(Map<String, Reference> refMap) {
121 List<String> possibilities = new ArrayList<>(refMap.keySet());
122 Collections.sort(possibilities);
123 if (refMap.keySet().size()>0) {
124 refMap.put("Nothing matches, create a new reference",null);
125 possibilities.add(0, "Nothing matches, create a new reference");
126 } else {
127 return null;
128 }
129
130 JTextArea textArea = new JTextArea("Which existing reference should be used?");
131 JScrollPane scrollPane = new JScrollPane(textArea);
132 textArea.setLineWrap(true);
133 textArea.setWrapStyleWord(true);
134 scrollPane.setPreferredSize( new Dimension( 700, 50 ) );
135
136 String s = null;
137 while (s == null) {
138 s= (String)JOptionPane.showInputDialog(
139 null,
140 scrollPane,
141 "Please select a reference in the list",
142 JOptionPane.PLAIN_MESSAGE,
143 null,
144 possibilities.toArray(),
145 "ABCD reference");
146 }
147 return refMap.get(s);
148 }
149
150 /**
151 * @param refMap
152 * @param iReferenceService
153 * @param docSources
154 * @return
155 */
156 public List<OriginalSourceBase> askForSource(Map<String, OriginalSourceBase> refMap, String currentElement, String blabla,
157 IReferenceService iReferenceService, List<String> docSources) {
158
159 // System.out.println(refMap);
160 List<String> possibilities = new ArrayList<> (refMap.keySet());
161
162 Set<String> all = new HashSet<>();
163 all.addAll(possibilities);
164
165 List<String> allList = new ArrayList<String>();
166 allList.addAll(all);
167 Collections.sort(allList);
168 allList.add(0, "Create a new source");
169
170 JLabel label = new JLabel(blabla);
171
172 sources=new ArrayList<String>();
173
174 JPanel checkPanel = null;
175 ButtonGroup group = null;
176 JScrollPane scrollPane = null;
177
178 JRadioButton jcb = null;
179
180 Object[] options = {"Add and close", "Add and continue - I want to add more sources","Close without adding anything"};
181
182 // System.out.println(docSources);
183 int n=1;
184 while (n==1){
185 group = new ButtonGroup();
186 checkPanel = new JPanel();
187 checkPanel.setLayout(new BoxLayout(checkPanel, BoxLayout.Y_AXIS));
188 // allList.removeAll(sources);
189 scrollPane = new JScrollPane(checkPanel);
190 scrollPane.setPreferredSize( new Dimension( 700, 300 ) );
191
192 checkPanel.add(label);
193
194 for (String ch:allList){
195 if (StringUtils.isBlank(ch)) {
196 continue;
197 }
198 // System.out.println("HOP ="+ch+"=");
199 if(docSources.contains(ch)) {
200 jcb = new JRadioButton("<html>"+ch.replace("---", "<br/>")+"</html>");
201 jcb.setForeground(Color.blue);
202 } else {
203 jcb = new JRadioButton("<html>"+ch.replace("---", "<br/>")+"</html>");
204 jcb.setForeground(Color.black);
205 }
206 jcb.addItemListener(this);
207 group.add(jcb);
208 checkPanel.add(jcb);
209 }
210
211 n = JOptionPane.showOptionDialog(null,
212 scrollPane,
213 "Choose a source for "+currentElement +"(in blue the source from the document)",
214 JOptionPane.YES_NO_CANCEL_OPTION,
215 JOptionPane.QUESTION_MESSAGE,
216 null,
217 options,
218 options[1]);
219 if(n<3 && !currentSource.isEmpty() && !currentSource.equalsIgnoreCase("Create a new source")) {
220 sources.add(currentSource);
221 }
222 // System.out.println("current source: "+currentSource);
223 if(currentSource.equalsIgnoreCase("Create a new source")){
224 String a = createNewSource();
225 if (a!=null && !a.isEmpty()) {
226 sources.add(a);
227 }
228 }
229 }
230
231 List<OriginalSourceBase> dess = new ArrayList<>();
232 for (String src:sources){
233 if (refMap.get(src) !=null) {
234 dess.add(refMap.get(src));
235 }
236 else{
237 Reference re = null;
238 String titlecache="";
239 String micro="";
240 if (src.indexOf("---")>-1){
241 titlecache = src.split("---")[0].trim();
242 micro=src.split("---")[1].trim();
243 }
244 else{
245 titlecache= src.split("---")[0].trim();
246 }
247
248 List<Reference> references = iReferenceService.list(Reference.class, null, null, null, null);
249 for (Reference reference:references){
250 if (reference.getTitleCache().equalsIgnoreCase(titlecache)) {
251 re=reference;
252 }
253 }
254 if(re == null){
255 re = ReferenceFactory.newGeneric();
256 re.setTitleCache(titlecache);
257 iReferenceService.saveOrUpdate(re);
258 }
259
260 dess.add(IdentifiableSource.NewInstance(OriginalSourceType.Import,null, null, re,micro));
261 }
262 }
263 return dess;
264 }
265
266 public String createNewReference() {
267 JTextArea textArea = new JTextArea("How should the reference be named ?");
268 JScrollPane scrollPane = new JScrollPane(textArea);
269 textArea.setLineWrap(true);
270 textArea.setWrapStyleWord(true);
271 scrollPane.setPreferredSize( new Dimension( 500, 50 ) );
272
273 String s = null;
274 while (s == null) {
275 s= (String)JOptionPane.showInputDialog(
276 null,
277 scrollPane,
278 "Get full reference name",
279 JOptionPane.PLAIN_MESSAGE,
280 null,
281 null,
282 "ABCD Import from XML");
283 }
284 return s;
285 }
286
287 public String createNewSource() {
288 JTextArea textArea = new JTextArea("How should the source be named? If there is a citation detail, prefix it with 3 minus signs ('---').");
289 JScrollPane scrollPane = new JScrollPane(textArea);
290 textArea.setLineWrap(true);
291 textArea.setWrapStyleWord(true);
292 scrollPane.setPreferredSize( new Dimension( 500, 50 ) );
293
294 String s = null;
295 while (s == null) {
296 s= (String)JOptionPane.showInputDialog(
297 null,
298 scrollPane,
299 "Get full source name",
300 JOptionPane.PLAIN_MESSAGE,
301 null,
302 null,
303 "ABCD Import from XML");
304 }
305 return s;
306 }
307
308 public TaxonDescription askForDescriptionGroup(Set<TaxonDescription> descriptions) {
309 JTextArea textArea = new JTextArea("One or several description group(s) does already exist for this taxon.");
310 JScrollPane scrollPane = new JScrollPane(textArea);
311 textArea.setLineWrap(true);
312 textArea.setWrapStyleWord(true);
313 scrollPane.setPreferredSize( new Dimension( 700, 50 ) );
314
315 Map<String,TaxonDescription> descrMap = new HashMap<String, TaxonDescription>();
316
317 int descCnt=1;
318 for (TaxonDescription description : descriptions){
319 // System.out.println("descr. titlecache "+description.getTitleCache());
320 Set<IdentifiableSource> sources = description.getTaxon().getSources();
321 sources.addAll(description.getSources());
322 List<String> src=new ArrayList<String>();
323 for (IdentifiableSource s:sources) {
324 src.add(s.getCitation().getTitleCache());
325 }
326 List<String> srcb = new ArrayList<String>(new HashSet<>(src));
327 if (srcb.size()>0) {
328 if(descrMap.containsKey(descCnt+": "+description.getTitleCache()+"("+StringUtils.join(srcb,";")+")")) {
329 descCnt+=1;
330 }
331 descrMap.put(descCnt+": "+description.getTitleCache()+"("+StringUtils.join(srcb,";")+")",description);
332 }
333 else {
334 if(descrMap.containsKey(description.getTitleCache())) {
335 descCnt+=1;
336 }
337 descrMap.put(descCnt+": "+description.getTitleCache(),description);
338 // for (IdentifiableSource source:sources){
339 // if(ref.equals(source.getCitation())) {
340 // taxonDescription = description;
341 // }
342 // }
343 }
344 }
345 List<String> possibilities = new ArrayList<>(descrMap.keySet());
346 if (possibilities.size()==0) {
347 return null;
348 }
349 Collections.sort(possibilities);
350
351 descrMap.put("No, add a brand new description group", null);
352 possibilities.add(0, "No, add a brand new description group");
353
354 String s = null;
355 while (s == null) {
356 s= (String)JOptionPane.showInputDialog(
357 null,
358 scrollPane,
359 "What should be done? Should an existing group be reused ? ",
360 JOptionPane.PLAIN_MESSAGE,
361 null,
362 possibilities.toArray(),
363 "No, add a brand new description group");
364 }
365
366 if (descrMap.get(s) !=null) {
367 return descrMap.get(s);
368 } else {
369 return null;
370 }
371 }
372
373 /**
374 * Look if the same name already exists in the ALL classifications and ask the user to select one or none.
375 * @param scientificName
376 * @param taxonList
377 * @return null if not found, or the selected Taxon
378 */
379 @SuppressWarnings("rawtypes")
380 public Taxon askWhereToFixData(String scientificName, List<TaxonBase> taxonList, Classification classification) {
381 Map<String,TaxonNode> classMap = new HashMap<>();
382 boolean sameClassification=false;
383 Taxon n = null;
384 for (TaxonBase taxonBase: taxonList){
385 if(taxonBase.isInstanceOf(Taxon.class)){
386 Taxon taxon = HibernateProxyHelper.deproxy(taxonBase, Taxon.class);
387 for (TaxonNode node : taxon.getTaxonNodes()){
388 classMap.put("Reuse the one from the classification \""+node.getClassification().getTitleCache()+"\"", node);
389 if (node.getClassification().getUuid().equals(classification.getUuid())) {
390 sameClassification=true;
391 n=node.getTaxon();
392 }
393 }
394 }
395 }
396 if (classMap.keySet().size()==1 && sameClassification) {
397 return n;
398 }
399
400 JTextArea textArea = new JTextArea("The same taxon ("+scientificName+") already exists in an other classification.");
401 JScrollPane scrollPane = new JScrollPane(textArea);
402 textArea.setLineWrap(true);
403 textArea.setWrapStyleWord(true);
404 scrollPane.setPreferredSize( new Dimension( 700, 50 ) );
405
406 List<String> possibilities = new ArrayList<String> (classMap.keySet());
407 if (possibilities.size()==0) {
408 return null;
409 }
410 Collections.sort(possibilities);
411 if(!sameClassification){
412 classMap.put("Add a brand new Taxon to the current classification, no recycling please", null);
413 possibilities.add(0, "Add a brand new Taxon to the current classification, no recycling please");
414 }
415 String s = null;
416 while (s == null) {
417 s= (String)JOptionPane.showInputDialog(
418 null,
419 scrollPane,
420 "What should be done? ",
421 JOptionPane.PLAIN_MESSAGE,
422 null,
423 possibilities.toArray(),
424 "Add a brand new Taxon to the current classification, no recycling please");
425 }
426
427 if (classMap.get(s) !=null) {
428 return classMap.get(s).getTaxon();
429 } else {
430 return null;
431 }
432 }
433
434 /**
435 * Look if the same TaxonBase already exists in the SAME classification
436 * @param taxonBaseList
437 * @return null if not found, or the corresponding Taxon
438 */
439 @SuppressWarnings("rawtypes")
440 public Taxon lookForTaxaIntoCurrentClassification(List<TaxonBase> taxonBaseList, Classification classification) {
441 Taxon taxonFound =null;
442 for (TaxonBase taxonBase:taxonBaseList){
443 if(taxonBase.isInstanceOf(Taxon.class)){
444 Taxon taxon = HibernateProxyHelper.deproxy(taxonBase, Taxon.class);
445 for (TaxonNode node : taxon.getTaxonNodes()){
446 UUID classUuid = node.getClassification().getUuid();
447 if (classification.getUuid().equals(classUuid)){
448 taxonFound=taxon;
449 }
450 }
451 }
452 }
453 return taxonFound;
454 }
455
456 List<String> sources = new ArrayList<>();
457 String currentSource = "";
458
459 @Override
460 public void itemStateChanged(ItemEvent e) {
461 JRadioButton cb = (JRadioButton) e.getItem();
462 int state = e.getStateChange();
463 if (state == ItemEvent.SELECTED) {
464 currentSource=cb.getText().replace("</html>", "").replace("<html>","")
465 .replace("<br/>","---").replace("<font color=\"blue\">","").replace("</font>","");
466 } else {
467 currentSource="";
468 }
469 }
470 }