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