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