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