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