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