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