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