Merge branch 'develop' into bulkEditorE4
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / e4 / TaxonEditorInputE4.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.e4;
11
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import org.eclipse.jface.resource.ImageDescriptor;
21 import org.eclipse.ui.IEditorInput;
22 import org.eclipse.ui.IMemento;
23 import org.eclipse.ui.IPersistableElement;
24
25 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
26 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
27 import eu.etaxonomy.cdm.api.service.IClassificationService;
28 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
29 import eu.etaxonomy.cdm.api.service.ITaxonService;
30 import eu.etaxonomy.cdm.model.common.CdmBase;
31 import eu.etaxonomy.cdm.model.name.TaxonName;
32 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
33 import eu.etaxonomy.cdm.model.taxon.Synonym;
34 import eu.etaxonomy.cdm.model.taxon.Taxon;
35 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
36 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
37 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
38 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
39 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
40 import eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput;
41 import eu.etaxonomy.taxeditor.editor.ChooseFromMultipleTaxonNodesDialog;
42 import eu.etaxonomy.taxeditor.editor.TaxonEditorInputFactory;
43 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
44 import eu.etaxonomy.taxeditor.model.DataChangeBridge;
45 import eu.etaxonomy.taxeditor.model.MessagingUtils;
46 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
47 import eu.etaxonomy.taxeditor.store.CdmStore;
48
49
50 /**
51 *
52 * @author pplitzner
53 * @date Aug 24, 2017
54 *
55 */
56 public class TaxonEditorInputE4 extends CdmEntitySessionInput implements IEditorInput, IConversationEnabled, IPersistableElement {
57
58 private static final String INCORRECT_STATE = Messages.TaxonEditorInput_INCORRECT_STATE;
59
60 private final ConversationHolder conversation;
61
62 private TaxonNode taxonNode;
63
64 private TaxonEditorInputDataChangeBehaviourE4 dataChangeBehavior;
65
66 private TaxonBase initiallySelectedTaxonBase;
67
68 private enum CdmType {
69 TAXON_NODE,
70 TAXON_BASE,
71 PARENT_TAXON_NODE
72 }
73
74 private TaxonEditorInputE4(UUID uuid, CdmType type) {
75 super(true);
76 this.conversation = CdmStore.createConversation();
77 switch(type) {
78 case PARENT_TAXON_NODE:
79 initForParentTaxonNode(uuid);
80 break;
81 case TAXON_BASE:
82 initForTaxonBase(uuid);
83 break;
84 case TAXON_NODE:
85 initForTaxonNode(uuid);
86 break;
87 }
88 }
89
90 private void init(TaxonNode taxonNode) {
91 this.taxonNode = taxonNode;
92 }
93
94
95 private void initForTaxonNode(UUID taxonNodeUuid) {
96
97
98 TaxonNode taxonNode = CdmStore.getService(ITaxonNodeService.class).load(taxonNodeUuid, getTaxonNodePropertyPaths());
99
100 if(taxonNode == null){
101 MessagingUtils.warningDialog(Messages.TaxonEditorInput_NOT_IMPLEMENTED, TaxonEditorInputE4.class, Messages.TaxonEditorInput_NOT_IMPLEMENTED_MESSAGE);
102 }
103 init(taxonNode);
104
105 }
106
107 private void initForTaxonBase(UUID taxonBaseUuid) {
108 TaxonBase taxonBase = CdmStore.getService(ITaxonService.class).load(taxonBaseUuid, getTaxonBasePropertyPaths());
109 if (taxonBase != null){
110 if(taxonBase.isInstanceOf(Taxon.class)){
111 Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
112
113 if (taxon.getTaxonNodes().size() == 0 && taxon.isMisapplication()){
114 // TODO get accepted taxon
115 MessagingUtils.info(Messages.TaxonEditorInput_OPEN_MISSAPPLIED_NAME);
116
117 Set<Taxon> acceptedTaxa = new HashSet<Taxon>();
118 Set<TaxonRelationship> relations = taxon.getRelationsFromThisTaxon();
119 for(TaxonRelationship relation : relations){
120 if(relation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){
121 acceptedTaxa.add(relation.getToTaxon());
122 }
123 }
124 setInputForMultipleTaxa(conversation, acceptedTaxa);
125
126 }else{
127 setInputForMultipleNodes(conversation, taxon.getTaxonNodes());
128 }
129 }else if(taxonBase instanceof Synonym){
130 Synonym synonym = (Synonym) taxonBase;
131
132 Set<Taxon> taxa = new HashSet<>();
133 Taxon taxon = synonym.getAcceptedTaxon();
134 if (taxon != null){
135 taxa.add(taxon);
136 }
137 setInputForMultipleTaxa(conversation, taxa);
138 }
139 }
140 }
141
142
143 private void initForParentTaxonNode(UUID parentNodeUuid){
144
145
146 TaxonName name = PreferencesUtil.getPreferredNomenclaturalCode().getNewTaxonNameInstance(null);
147 ITaxonTreeNode parentNode = CdmStore.getService(IClassificationService.class).getTreeNodeByUuid(parentNodeUuid);
148
149 Taxon newTaxon = Taxon.NewInstance(name, parentNode.getReference());
150 TaxonNode newTaxonNode = parentNode.addChildTaxon(newTaxon, parentNode.getReference(), parentNode.getMicroReference());
151
152 // add the new taxon to the editors persistence context
153 UUID newTaxonNodeUuid = CdmStore.getService(ITaxonNodeService.class).save(newTaxonNode).getUuid();
154
155 initForTaxonNode(newTaxonNodeUuid);
156 }
157
158 private void setInputForMultipleNodes(ConversationHolder conversation, Set<TaxonNode> taxonNodes){
159 if(taxonNodes.size() == 1){
160 TaxonNode taxonNode = taxonNodes.iterator().next();
161 init(taxonNode);
162 }else if(taxonNodes.size() > 1){
163 TaxonNode taxonNode = ChooseFromMultipleTaxonNodesDialog.choose(taxonNodes);
164 if(taxonNode != null){
165 init(taxonNode);
166 }
167 } else if (taxonNodes.size() == 0) {
168 // this is an undesired state
169 MessagingUtils.warningDialog(INCORRECT_STATE,TaxonEditorInputE4.class,Messages.TaxonEditorInput_TAXON_NOT_IN_CLASSIFICATION);
170 }
171 }
172
173 private void setInputForMultipleTaxa(ConversationHolder conversation, Set<Taxon> taxa){
174 if(taxa.size() == 1){
175 Taxon taxon = taxa.iterator().next();
176 Set<TaxonNode> nodes = taxon.getTaxonNodes();
177 setInputForMultipleNodes(conversation, nodes);
178 }else if(taxa.size() > 1){
179 Set<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
180 for ( Taxon taxon : taxa ){
181 taxonNodes.addAll(taxon.getTaxonNodes());
182 }
183 setInputForMultipleNodes(conversation, taxonNodes);
184 }else if(taxa.size() == 0){
185 // this is an undesired state
186 MessagingUtils.warningDialog(INCORRECT_STATE, TaxonEditorInputE4.class, Messages.TaxonEditorInput_NO_ACCEPTED_TAXON_PRESENT);
187 }
188 }
189
190 public static TaxonEditorInputE4 NewInstance(UUID taxonNodeUuid) throws Exception {
191 return new TaxonEditorInputE4(taxonNodeUuid, CdmType.TAXON_NODE);
192
193 }
194
195 public static TaxonEditorInputE4 NewInstanceFromTaxonBase(UUID taxonBaseUuid){
196 return new TaxonEditorInputE4(taxonBaseUuid, CdmType.TAXON_BASE);
197 }
198
199
200 public static TaxonEditorInputE4 NewEmptyInstance(UUID parentNodeUuid){
201 return new TaxonEditorInputE4(parentNodeUuid, CdmType.PARENT_TAXON_NODE);
202 }
203
204 @Override
205 public boolean exists() {
206 return taxonNode != null;
207 }
208
209 @Override
210 public ImageDescriptor getImageDescriptor() {
211 return null;
212 }
213
214 @Override
215 public String getName() {
216 if(getTaxon() == null){
217 return null;
218 }
219 TaxonName name = getTaxon().getName();
220 if (name == null || name.getTitleCache() == null) {
221 return Messages.TaxonEditorInput_NEW_TAXON;
222 } else {
223 return name.getTitleCache();
224 }
225 }
226
227 @Override
228 public IPersistableElement getPersistable() {
229 return null;
230 }
231
232 @Override
233 public String getToolTipText() {
234 return getName();
235 }
236
237 /** {@inheritDoc} */
238 @Override
239 public Object getAdapter(Class adapter) {
240
241 if (adapter == Taxon.class) {
242 return getTaxon();
243 }
244
245 if (adapter == TaxonNode.class) {
246 return taxonNode;
247 }
248
249 return null;
250 }
251
252 /**
253 * {@inheritDoc}
254 *
255 * Overrides equals to ensure that a taxon can only be edited by
256 * one editor at a time.
257 */
258 @Override
259 public boolean equals(Object obj) {
260 if (TaxonEditorInputE4.class.equals(obj.getClass())
261 && getTaxon() != null
262 && getTaxon().equals(((TaxonEditorInputE4) obj).getTaxon())) {
263 if (((TaxonEditorInputE4) obj).getInitiallySelectedTaxonBase() != null){
264 setInitiallySelectedTaxonBase(((TaxonEditorInputE4) obj).getInitiallySelectedTaxonBase());
265 }
266 return true;
267 }
268 return false;
269 }
270
271 public Taxon getTaxon(){
272 Taxon taxon = CdmBase.deproxy(taxonNode.getTaxon(), Taxon.class);
273 return taxon;
274 }
275
276 public TaxonNode getTaxonNode() {
277 return taxonNode;
278 }
279
280 @Override
281 public ConversationHolder getConversationHolder() {
282 return conversation;
283 }
284
285 /** {@inheritDoc} */
286 @Override
287 public void update(CdmDataChangeMap events) {
288 if(dataChangeBehavior == null){
289 dataChangeBehavior = new TaxonEditorInputDataChangeBehaviourE4(this);
290 }
291
292 DataChangeBridge.handleDataChange(events, dataChangeBehavior);
293 }
294
295 @Override
296 public String getFactoryId() {
297 return TaxonEditorInputFactory.getFactoryId();
298 }
299
300 /** {@inheritDoc} */
301 @Override
302 public void saveState(IMemento memento) {
303 TaxonEditorInputFactoryE4.saveState(memento, this);
304 }
305
306
307 public void setInitiallySelectedTaxonBase(TaxonBase taxonBase) {
308 this.initiallySelectedTaxonBase = taxonBase;
309 }
310
311 public TaxonBase getInitiallySelectedTaxonBase() {
312 return initiallySelectedTaxonBase;
313 }
314
315 @Override
316 public List<TaxonNode> getRootEntities() {
317 return Arrays.asList(taxonNode);
318 }
319
320 @Override
321 public void merge() {
322 CdmStore.getService(ITaxonNodeService.class).merge(taxonNode, true);
323
324 }
325
326 @Override
327 public Map<Object, List<String>> getPropertyPathsMap() {
328 return null;
329 }
330
331 private List<String> getTaxonNodePropertyPaths() {
332 List<String> taxonNodePropertyPaths = new ArrayList<String>();
333 for(String propertyPath : getTaxonBasePropertyPaths()) {
334 taxonNodePropertyPaths.add("taxon." + propertyPath); //$NON-NLS-1$
335 }
336 return taxonNodePropertyPaths;
337 }
338
339 private List<String> getTaxonBasePropertyPaths() {
340 List<String> taxonBasePropertyPaths = Arrays.asList(new String[] {
341 "sec", //$NON-NLS-1$
342 "createdBy", //$NON-NLS-1$
343 "updatedBy", //$NON-NLS-1$
344 "annotations", //$NON-NLS-1$
345 "markers", //$NON-NLS-1$
346 "credits", //$NON-NLS-1$
347 "extensions", //$NON-NLS-1$
348 "rights", //$NON-NLS-1$
349 "sources", //$NON-NLS-1$
350 "descriptions", //$NON-NLS-1$
351 "relationsToThisTaxon", //$NON-NLS-1$
352 "relationsFromThisTaxon", //$NON-NLS-1$
353 "taxonNodes", //$NON-NLS-1$
354 "descriptions.descriptionElements.feature", //$NON-NLS-1$
355 "descriptions.descriptionElements.area", //$NON-NLS-1$
356 "descriptions.descriptionElements.status", //$NON-NLS-1$
357 "descriptions.markers", //$NON-NLS-1$
358 "name.descriptions", //$NON-NLS-1$
359 "name.typeDesignations", //$NON-NLS-1$
360 "name.status", //$NON-NLS-1$
361 "name.nomenclaturalReference.inReference", //$NON-NLS-1$
362 "name.taxonBases.taxonNodes", //$NON-NLS-1$
363 "name.relationsFromThisName", //$NON-NLS-1$
364 "name.relationsToThisName", //$NON-NLS-1$
365 "name.homotypicalGroup.typifiedNames.taxonBases.synonymRelations.synonym.name.status", //$NON-NLS-1$
366 "name.homotypicalGroup.typifiedNames.relationsToThisName.fromName", //$NON-NLS-1$
367 "synonymRelations.synonym.name.status.type", //$NON-NLS-1$
368 "synonymRelations.synonym.name.relationsToThisName.fromName", //$NON-NLS-1$
369 "synonymRelations.synonym.name.nomenclaturalReference.inReference.authorship", //$NON-NLS-1$
370 "synonymRelations.synonym.name.nomenclaturalReference.authorship", //$NON-NLS-1$
371 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.synonymRelations" //$NON-NLS-1$
372 });
373
374 return taxonBasePropertyPaths;
375 }
376
377 }