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