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