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