Merge branch 'release/4.4.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / TaxonEditorInput.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.Arrays;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import org.eclipse.jface.resource.ImageDescriptor;
21 import org.eclipse.ui.IEditorInput;
22 import org.eclipse.ui.IMemento;
23 import org.eclipse.ui.IPersistableElement;
24
25 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
26 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
27 import eu.etaxonomy.cdm.api.service.IClassificationService;
28 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
29 import eu.etaxonomy.cdm.api.service.ITaxonService;
30 import eu.etaxonomy.cdm.model.common.CdmBase;
31 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
32 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
33 import eu.etaxonomy.cdm.model.taxon.Synonym;
34 import eu.etaxonomy.cdm.model.taxon.Taxon;
35 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
36 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
37 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
38 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
39 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
40 import eu.etaxonomy.taxeditor.model.DataChangeBridge;
41 import eu.etaxonomy.taxeditor.model.MessagingUtils;
42 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
43 import eu.etaxonomy.taxeditor.store.CdmStore;
44
45
46 /**
47 * <p>TaxonEditorInput class.</p>
48 *
49 * @author n.hoffmann
50 * @created 19.03.2009
51 * @version 1.0
52 */
53 public class TaxonEditorInput extends CdmEntitySessionInput implements IEditorInput, IConversationEnabled, IPersistableElement {
54
55 private final ConversationHolder conversation;
56
57 private TaxonNode taxonNode;
58
59 private TaxonEditorInputDataChangeBehaviour dataChangeBehavior;
60
61 private TaxonBase initiallySelectedTaxonBase;
62
63 private enum CdmType {
64 TAXON_NODE,
65 TAXON_BASE,
66 PARENT_TAXON_NODE
67 }
68
69 private TaxonEditorInput(UUID uuid, CdmType type) {
70 super(true);
71 this.conversation = CdmStore.createConversation();
72 switch(type) {
73 case PARENT_TAXON_NODE:
74 initForParentTaxonNode(uuid);
75 break;
76 case TAXON_BASE:
77 initForTaxonBase(uuid);
78 break;
79 case TAXON_NODE:
80 initForTaxonNode(uuid);
81 break;
82 }
83 }
84
85 private void init(TaxonNode taxonNode) {
86 this.taxonNode = taxonNode;
87 }
88
89
90 /**
91 * <p>NewInstance</p>
92 *
93 * @param taxonNodeUuid a {@link java.util.UUID} object.
94 * @return a {@link eu.etaxonomy.taxeditor.editor.TaxonEditorInput} object.
95 * @throws java.lang.Exception if any.
96 */
97 private void initForTaxonNode(UUID taxonNodeUuid) {
98
99
100 TaxonNode taxonNode = CdmStore.getService(ITaxonNodeService.class).load(taxonNodeUuid, getTaxonNodePropertyPaths());
101
102 if(taxonNode == null){
103 MessagingUtils.warningDialog("Not yet implemented", TaxonEditorInput.class, "Selected element is not type TaxonBase.");
104 }
105 init(taxonNode);
106
107 }
108
109 private void initForTaxonBase(UUID taxonBaseUuid) {
110 TaxonBase taxonBase = CdmStore.getService(ITaxonService.class).load(taxonBaseUuid, getTaxonBasePropertyPaths());
111 if (taxonBase != null){
112 if(taxonBase.isInstanceOf(Taxon.class)){
113 Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
114
115 if (taxon.getTaxonNodes().size() == 0 && taxon.isMisapplication()){
116 // TODO get accepted taxon
117 MessagingUtils.info("trying to open Mispplied Name ");
118
119 Set<Taxon> acceptedTaxa = new HashSet<Taxon>();
120 Set<TaxonRelationship> relations = taxon.getRelationsFromThisTaxon();
121 for(TaxonRelationship relation : relations){
122 if(relation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){
123 acceptedTaxa.add(relation.getToTaxon());
124 }
125 }
126 setInputForMultipleTaxa(conversation, acceptedTaxa);
127
128 }else{
129 setInputForMultipleNodes(conversation, taxon.getTaxonNodes());
130 }
131 }else if(taxonBase instanceof Synonym){
132 Synonym synonym = (Synonym) taxonBase;
133
134 Set<Taxon> taxa = new HashSet<>();
135 Taxon taxon = synonym.getAcceptedTaxon();
136 if (taxon != null){
137 taxa.add(taxon);
138 }
139 setInputForMultipleTaxa(conversation, taxa);
140 }
141 }
142 }
143
144
145 /**
146 * <p>NewEmptyInstance</p>
147 *
148 * @param parentNodeUuid a {@link java.util.UUID} object.
149 * @return a {@link eu.etaxonomy.taxeditor.editor.TaxonEditorInput} object.
150 */
151 private void initForParentTaxonNode(UUID parentNodeUuid){
152
153
154 TaxonNameBase<?, ?> name = PreferencesUtil.getPreferredNomenclaturalCode().getNewTaxonNameInstance(null);
155 ITaxonTreeNode parentNode = CdmStore.getService(IClassificationService.class).getTreeNodeByUuid(parentNodeUuid);
156
157 Taxon newTaxon = Taxon.NewInstance(name, parentNode.getReference());
158 TaxonNode newTaxonNode = parentNode.addChildTaxon(newTaxon, parentNode.getReference(), parentNode.getMicroReference());
159
160 // add the new taxon to the editors persistence context
161 UUID newTaxonNodeUuid = CdmStore.getService(ITaxonNodeService.class).save(newTaxonNode).getUuid();
162
163 initForTaxonNode(newTaxonNodeUuid);
164 }
165
166
167
168
169 private void setInputForMultipleNodes(ConversationHolder conversation, Set<TaxonNode> taxonNodes){
170 if(taxonNodes.size() == 1){
171 TaxonNode taxonNode = taxonNodes.iterator().next();
172 init(taxonNode);
173 }else if(taxonNodes.size() > 1){
174 TaxonNode taxonNode = ChooseFromMultipleTaxonNodesDialog.choose(taxonNodes);
175 if(taxonNode != null){
176 init(taxonNode);
177 }
178 } else if (taxonNodes.size() == 0) {
179 // this is an undesired state
180 MessagingUtils.warningDialog("Incorrect state",TaxonEditorInput.class,"The accepted "
181 + "taxon is not part of any classification. Editing with the "
182 + "name editor is currently not implemented. Try to edit the taxon with the bulk editor.");
183 }
184 }
185
186 private void setInputForMultipleTaxa(ConversationHolder conversation, Set<Taxon> taxa){
187 if(taxa.size() == 1){
188 Taxon taxon = taxa.iterator().next();
189 Set<TaxonNode> nodes = taxon.getTaxonNodes();
190 setInputForMultipleNodes(conversation, nodes);
191 }else if(taxa.size() > 1){
192 Set<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
193 for ( Taxon taxon : taxa ){
194 taxonNodes.addAll(taxon.getTaxonNodes());
195 }
196 setInputForMultipleNodes(conversation, taxonNodes);
197 }else if(taxa.size() == 0){
198 // this is an undesired state
199 MessagingUtils.warningDialog("Incorrect state", TaxonEditorInput.class, "Trying to open accepted taxon for a synonym or misapplication but" +
200 " no accepted taxa are present. This should not have happened.");
201 }
202 }
203
204 /**
205 * <p>NewInstance</p>
206 *
207 * @param taxonNodeUuid a {@link java.util.UUID} object.
208 * @return a {@link eu.etaxonomy.taxeditor.editor.TaxonEditorInput} object.
209 * @throws java.lang.Exception if any.
210 */
211 public static TaxonEditorInput NewInstance(UUID taxonNodeUuid) throws Exception {
212 return new TaxonEditorInput(taxonNodeUuid, CdmType.TAXON_NODE);
213
214 }
215
216 /**
217 * <p>NewInstanceFromTaxonBase</p>
218 *
219 * @param taxonBaseUuid a {@link java.util.UUID} object.
220 * @return a {@link eu.etaxonomy.taxeditor.editor.TaxonEditorInput} object.
221 */
222 public static TaxonEditorInput NewInstanceFromTaxonBase(UUID taxonBaseUuid){
223 return new TaxonEditorInput(taxonBaseUuid, CdmType.TAXON_BASE);
224 }
225
226
227 /**
228 * <p>NewEmptyInstance</p>
229 *
230 * @param parentNodeUuid a {@link java.util.UUID} object.
231 * @return a {@link eu.etaxonomy.taxeditor.editor.TaxonEditorInput} object.
232 */
233 public static TaxonEditorInput NewEmptyInstance(UUID parentNodeUuid){
234 return new TaxonEditorInput(parentNodeUuid, CdmType.PARENT_TAXON_NODE);
235 }
236
237 /* (non-Javadoc)
238 * @see org.eclipse.ui.IEditorInput#exists()
239 */
240 /**
241 * <p>exists</p>
242 *
243 * @return a boolean.
244 */
245 @Override
246 public boolean exists() {
247 return taxonNode != null;
248 }
249
250 /* (non-Javadoc)
251 * @see org.eclipse.ui.IEditorInput#getImageDescriptor()
252 */
253 /**
254 * <p>getImageDescriptor</p>
255 *
256 * @return a {@link org.eclipse.jface.resource.ImageDescriptor} object.
257 */
258 @Override
259 public ImageDescriptor getImageDescriptor() {
260 return null;
261 }
262
263 /* (non-Javadoc)
264 * @see org.eclipse.ui.IEditorInput#getName()
265 */
266 /**
267 * <p>getName</p>
268 *
269 * @return a {@link java.lang.String} object.
270 */
271 @Override
272 public String getName() {
273 if(getTaxon() == null){
274 return null;
275 }
276 TaxonNameBase<?, ?> name = getTaxon().getName();
277 if (name == null || name.getTitleCache() == null) {
278 return "New taxon";
279 } else {
280 return name.getTitleCache();
281 }
282 }
283
284 /* (non-Javadoc)
285 * @see org.eclipse.ui.IEditorInput#getPersistable()
286 */
287 /**
288 * <p>getPersistable</p>
289 *
290 * @return a {@link org.eclipse.ui.IPersistableElement} object.
291 */
292 @Override
293 public IPersistableElement getPersistable() {
294 // if(CdmStore.isActive()){
295 // TaxonNode test = CdmStore.getTaxonTreeService().getTaxonNodeByUuid(taxonNode.getUuid());
296 // boolean isPersistable = CdmStore.getTaxonTreeService().getTaxonNodeByUuid(taxonNode.getUuid()) != null;
297 // if (isPersistable) {
298 // return this;
299 // }
300 // }
301 return null;
302 }
303
304 /* (non-Javadoc)
305 * @see org.eclipse.ui.IEditorInput#getToolTipText()
306 */
307 /**
308 * <p>getToolTipText</p>
309 *
310 * @return a {@link java.lang.String} object.
311 */
312 @Override
313 public String getToolTipText() {
314 return getName();
315 }
316
317 /* (non-Javadoc)
318 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
319 */
320 /** {@inheritDoc} */
321 @Override
322 public Object getAdapter(Class adapter) {
323
324 if (adapter == Taxon.class) {
325 return getTaxon();
326 }
327
328 if (adapter == TaxonNode.class) {
329 return taxonNode;
330 }
331
332 return null;
333 }
334
335 /**
336 * {@inheritDoc}
337 *
338 * Overrides equals to ensure that a taxon can only be edited by
339 * one editor at a time.
340 */
341 @Override
342 public boolean equals(Object obj) {
343 if (TaxonEditorInput.class.equals(obj.getClass())
344 && getTaxon() != null
345 && getTaxon().equals(((TaxonEditorInput) obj).getTaxon())) {
346 if (((TaxonEditorInput) obj).getInitiallySelectedTaxonBase() != null){
347 setInitiallySelectedTaxonBase(((TaxonEditorInput) obj).getInitiallySelectedTaxonBase());
348 }
349 return true;
350 }
351 return false;
352 }
353
354 /**
355 * <p>getTaxon</p>
356 *
357 * @return the taxon
358 */
359 public Taxon getTaxon(){
360 Taxon taxon = CdmBase.deproxy(taxonNode.getTaxon(), Taxon.class);
361 return taxon;
362 }
363
364 /**
365 * <p>Getter for the field <code>taxonNode</code>.</p>
366 *
367 * @return the taxonNode
368 */
369 public TaxonNode getTaxonNode() {
370 return taxonNode;
371 }
372
373 /*
374 * (non-Javadoc)
375 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
376 */
377 /**
378 * <p>getConversationHolder</p>
379 *
380 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
381 */
382 @Override
383 public ConversationHolder getConversationHolder() {
384 return conversation;
385 }
386
387 /*
388 * (non-Javadoc)
389 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
390 */
391 /** {@inheritDoc} */
392 @Override
393 public void update(CdmDataChangeMap events) {
394 if(dataChangeBehavior == null){
395 dataChangeBehavior = new TaxonEditorInputDataChangeBehaviour(this);
396 }
397
398 DataChangeBridge.handleDataChange(events, dataChangeBehavior);
399 }
400
401 /* (non-Javadoc)
402 * @see org.eclipse.ui.IPersistableElement#getFactoryId()
403 */
404 /**
405 * <p>getFactoryId</p>
406 *
407 * @return a {@link java.lang.String} object.
408 */
409 @Override
410 public String getFactoryId() {
411 return TaxonEditorInputFactory.getFactoryId();
412 }
413
414 /* (non-Javadoc)
415 * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
416 */
417 /** {@inheritDoc} */
418 @Override
419 public void saveState(IMemento memento) {
420 TaxonEditorInputFactory.saveState(memento, this);
421 }
422
423
424 /**
425 * <p>Setter for the field <code>initiallySelectedTaxonBase</code>.</p>
426 *
427 * @param taxonBase a {@link eu.etaxonomy.cdm.model.taxon.TaxonBase} object.
428 */
429 public void setInitiallySelectedTaxonBase(TaxonBase taxonBase) {
430 this.initiallySelectedTaxonBase = taxonBase;
431 }
432
433 /**
434 * <p>Getter for the field <code>initiallySelectedTaxonBase</code>.</p>
435 *
436 * @return a {@link eu.etaxonomy.cdm.model.taxon.TaxonBase} object.
437 */
438 public TaxonBase getInitiallySelectedTaxonBase() {
439 return initiallySelectedTaxonBase;
440 }
441
442 // @Override
443 // public String toString() {
444 // return String.format("%s[%s]", this.getClass().getSimpleName(), getTaxon());
445 // }
446
447
448 /* (non-Javadoc)
449 * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getRootEntities()
450 */
451 @Override
452 public List<TaxonNode> getRootEntities() {
453 return Arrays.asList(taxonNode);
454 }
455
456 /* (non-Javadoc)
457 * @see eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput#merge()
458 */
459 @Override
460 public void merge() {
461 CdmStore.getService(ITaxonNodeService.class).merge(taxonNode, true);
462
463 }
464
465 @Override
466 public Map<Object, List<String>> getPropertyPathsMap() {
467 return null;
468 }
469
470 private List<String> getTaxonNodePropertyPaths() {
471 List<String> taxonNodePropertyPaths = new ArrayList<String>();
472 for(String propertyPath : getTaxonBasePropertyPaths()) {
473 taxonNodePropertyPaths.add("taxon." + propertyPath);
474 }
475 return taxonNodePropertyPaths;
476 }
477
478 private List<String> getTaxonBasePropertyPaths() {
479 List<String> taxonBasePropertyPaths = Arrays.asList(new String[] {
480 "sec",
481 "createdBy",
482 "updatedBy",
483 "annotations",
484 "markers",
485 "credits",
486 "extensions",
487 "rights",
488 "sources",
489 "descriptions",
490 "relationsToThisTaxon",
491 "relationsFromThisTaxon",
492 "taxonNodes",
493 "descriptions.descriptionElements.feature",
494 "descriptions.descriptionElements.area",
495 "descriptions.descriptionElements.status",
496 "descriptions.markers",
497 "name.descriptions",
498 "name.typeDesignations",
499 "name.status",
500 "name.nomenclaturalReference.inReference",
501 "name.taxonBases.taxonNodes",
502 "name.relationsFromThisName",
503 "name.relationsToThisName",
504 "name.homotypicalGroup.typifiedNames.taxonBases.synonymRelations.synonym.name.status",
505 "name.homotypicalGroup.typifiedNames.relationsToThisName.fromName",
506 "synonymRelations.synonym.name.status.type",
507 "synonymRelations.synonym.name.relationsToThisName.fromName",
508 "synonymRelations.synonym.name.nomenclaturalReference.inReference.authorship",
509 "synonymRelations.synonym.name.nomenclaturalReference.authorship",
510 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.synonymRelations"
511 });
512
513 return taxonBasePropertyPaths;
514 }
515
516 }