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