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