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