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