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