Project

General

Profile

Download (15.3 KB) Statistics
| Branch: | Tag: | Revision:
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.HashMap;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Map.Entry;
19
import java.util.Set;
20
import java.util.UUID;
21

    
22
import org.eclipse.e4.ui.di.UISynchronize;
23

    
24
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
25
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
26
import eu.etaxonomy.cdm.api.service.IClassificationService;
27
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
28
import eu.etaxonomy.cdm.api.service.ITaxonService;
29
import eu.etaxonomy.cdm.api.service.config.SynonymDeletionConfigurator;
30
import eu.etaxonomy.cdm.api.service.config.TaxonBaseDeletionConfigurator;
31
import eu.etaxonomy.cdm.api.service.config.TaxonDeletionConfigurator;
32
import eu.etaxonomy.cdm.model.common.CdmBase;
33
import eu.etaxonomy.cdm.model.name.TaxonName;
34
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
35
import eu.etaxonomy.cdm.model.taxon.Synonym;
36
import eu.etaxonomy.cdm.model.taxon.Taxon;
37
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
38
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
39
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
40
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
41
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
42
import eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput;
43
import eu.etaxonomy.taxeditor.editor.ChooseFromMultipleTaxonNodesDialog;
44
import eu.etaxonomy.taxeditor.editor.EditorUtil;
45
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
46
import eu.etaxonomy.taxeditor.model.DataChangeBridge;
47
import eu.etaxonomy.taxeditor.model.MessagingUtils;
48
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
49
import eu.etaxonomy.taxeditor.operation.AbstractPostTaxonOperation;
50
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
51
import eu.etaxonomy.taxeditor.store.CdmStore;
52

    
53

    
54
/**
55
 *
56
 * @author pplitzner
57
 * @date Aug 24, 2017
58
 *
59
 */
60
public class TaxonEditorInputE4  extends CdmEntitySessionInput implements IConversationEnabled {
61

    
62
    private static final String INCORRECT_STATE = Messages.TaxonEditorInput_INCORRECT_STATE;
63

    
64
    private final ConversationHolder conversation;
65

    
66
    private TaxonNode taxonNode;
67

    
68
    private Map<TaxonBase, TaxonBaseDeletionConfigurator> toDelete = new HashMap<>();
69
    private Set<TaxonBase> toSaveNew = new HashSet<>();
70

    
71
    private Set<AbstractPostTaxonOperation> operations = new HashSet<>();
72

    
73
    private TaxonEditorInputDataChangeBehaviourE4 dataChangeBehavior;
74

    
75
    private TaxonBase initiallySelectedTaxonBase;
76

    
77
    UISynchronize sync;
78

    
79

    
80
    public void setSync(UISynchronize sync) {
81
        this.sync = sync;
82
    }
83

    
84
    private enum CdmType {
85
        TAXON_NODE,
86
        TAXON_BASE,
87
        PARENT_TAXON_NODE
88
    }
89

    
90
    private TaxonEditorInputE4(UUID uuid, CdmType type) {
91
        super(true);
92
        this.conversation = CdmStore.createConversation();
93
        switch(type) {
94
        case PARENT_TAXON_NODE:
95
            initForParentTaxonNode(uuid);
96
            break;
97
        case TAXON_BASE:
98
            initForTaxonBase(uuid);
99
            break;
100
        case TAXON_NODE:
101
            initForTaxonNode(uuid);
102
            break;
103
        }
104
    }
105

    
106
    private void init(TaxonNode taxonNode) {
107
    	this.taxonNode = taxonNode;
108
    }
109

    
110

    
111
    private void initForTaxonNode(UUID taxonNodeUuid) {
112
    	this.getCdmEntitySession().bind();
113
        TaxonNode taxonNode = CdmStore.getService(ITaxonNodeService.class).load(taxonNodeUuid, getTaxonNodePropertyPaths());
114
        if(taxonNode == null){
115
            MessagingUtils.warningDialog(Messages.TaxonEditorInput_NOT_IMPLEMENTED, TaxonEditorInputE4.class, Messages.TaxonEditorInput_NOT_IMPLEMENTED_MESSAGE);
116
        }
117
        init(taxonNode);
118
        setInitiallySelectedTaxonBase(getTaxon());
119

    
120
    }
121

    
122
    private void initForTaxonBase(UUID taxonBaseUuid) {
123
    	this.getCdmEntitySession().bind();
124
        TaxonBase taxonBase = CdmStore.getService(ITaxonService.class).load(taxonBaseUuid, getTaxonBasePropertyPaths());
125
        if (taxonBase != null){
126
            if(taxonBase.isInstanceOf(Taxon.class)){
127
                Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
128
                setInitiallySelectedTaxonBase(taxon);
129

    
130
                if (taxon.getTaxonNodes().size() == 0 && taxon.isMisapplication()){
131
                    // TODO get accepted taxon
132
                    MessagingUtils.info(Messages.TaxonEditorInput_OPEN_MISSAPPLIED_NAME);
133

    
134
                    Set<Taxon> acceptedTaxa = new HashSet<Taxon>();
135
                    Set<TaxonRelationship> relations = taxon.getRelationsFromThisTaxon();
136
                    for(TaxonRelationship relation : relations){
137
                        if(relation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){
138
                            acceptedTaxa.add(relation.getToTaxon());
139
                        }
140
                    }
141
                    setInputForMultipleTaxa(conversation, acceptedTaxa);
142

    
143
                }else{
144
                    setInputForMultipleNodes(conversation, taxon.getTaxonNodes());
145
                }
146
            }else if(taxonBase instanceof Synonym){
147
                Synonym synonym = (Synonym) taxonBase;
148

    
149
                Set<Taxon> taxa = new HashSet<>();
150
                Taxon taxon = synonym.getAcceptedTaxon();
151
                if (taxon != null){
152
                	taxa.add(taxon);
153
                }
154
                setInputForMultipleTaxa(conversation, taxa);
155
                setInitiallySelectedTaxonBase(synonym);
156
            }
157
        }
158
    }
159

    
160

    
161
    private void initForParentTaxonNode(UUID parentNodeUuid){
162
    	this.getCdmEntitySession().bind();
163
        TaxonName name = PreferencesUtil.getPreferredNomenclaturalCode().getNewTaxonNameInstance(null);
164
        ITaxonTreeNode parentNode = CdmStore.getService(IClassificationService.class).getTreeNodeByUuid(parentNodeUuid);
165

    
166
        Taxon newTaxon = Taxon.NewInstance(name, parentNode.getReference());
167
        TaxonNode newTaxonNode = parentNode.addChildTaxon(newTaxon, parentNode.getReference(), parentNode.getMicroReference());
168

    
169
        // add the new taxon to the editors persistence context
170
        UUID newTaxonNodeUuid = CdmStore.getService(ITaxonNodeService.class).save(newTaxonNode).getUuid();
171

    
172
        initForTaxonNode(newTaxonNodeUuid);
173
    }
174

    
175
    private void setInputForMultipleNodes(ConversationHolder conversation, Set<TaxonNode> taxonNodes){
176
        if(taxonNodes.size() == 1){
177
            TaxonNode taxonNode = taxonNodes.iterator().next();
178
            taxonNode = CdmStore.getService(ITaxonNodeService.class).load(taxonNode.getUuid(), getTaxonNodePropertyPaths());
179
            init(taxonNode);
180
        }else if(taxonNodes.size() > 1){
181
            TaxonNode taxonNode = ChooseFromMultipleTaxonNodesDialog.choose(taxonNodes);
182
            taxonNode = CdmStore.getService(ITaxonNodeService.class).load(taxonNode.getUuid(), getTaxonNodePropertyPaths());
183
            if(taxonNode != null){
184
                init(taxonNode);
185
            }
186
        } else if (taxonNodes.size() == 0) {
187
            // this is an undesired state
188
            MessagingUtils.warningDialog(INCORRECT_STATE,TaxonEditorInputE4.class,Messages.TaxonEditorInput_TAXON_NOT_IN_CLASSIFICATION);
189
        }
190
    }
191

    
192
    private void setInputForMultipleTaxa(ConversationHolder conversation, Set<Taxon> taxa){
193
        if(taxa.size() == 1){
194
            Taxon taxon = taxa.iterator().next();
195
            Set<TaxonNode> nodes = taxon.getTaxonNodes();
196
            setInputForMultipleNodes(conversation, nodes);
197
        }else if(taxa.size() > 1){
198
            Set<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
199
            for ( Taxon taxon : taxa ){
200
                taxonNodes.addAll(taxon.getTaxonNodes());
201
            }
202
            setInputForMultipleNodes(conversation, taxonNodes);
203
        }else if(taxa.size() == 0){
204
            // this is an undesired state
205
            MessagingUtils.warningDialog(INCORRECT_STATE, TaxonEditorInputE4.class, Messages.TaxonEditorInput_NO_ACCEPTED_TAXON_PRESENT);
206
        }
207
    }
208

    
209
    public static TaxonEditorInputE4 NewInstance(UUID taxonNodeUuid) {
210
        return new TaxonEditorInputE4(taxonNodeUuid, CdmType.TAXON_NODE);
211

    
212
    }
213

    
214
    public static TaxonEditorInputE4 NewInstanceFromTaxonBase(UUID taxonBaseUuid){
215
        return new TaxonEditorInputE4(taxonBaseUuid, CdmType.TAXON_BASE);
216
    }
217

    
218

    
219
    public static TaxonEditorInputE4 NewEmptyInstance(UUID parentNodeUuid){
220
        return new TaxonEditorInputE4(parentNodeUuid, CdmType.PARENT_TAXON_NODE);
221
    }
222

    
223
    public Object getAdapter(Class adapter) {
224

    
225
        if (adapter == Taxon.class) {
226
            return getTaxon();
227
        }
228

    
229
        if (adapter == TaxonNode.class) {
230
            return taxonNode;
231
        }
232

    
233
        return null;
234
    }
235

    
236
    /**
237
     * {@inheritDoc}
238
     *
239
     * Overrides equals to ensure that a taxon can only be edited by
240
     * one editor at a time.
241
     */
242
    @Override
243
    public boolean equals(Object obj) {
244
        if (TaxonEditorInputE4.class.equals(obj.getClass())
245
                && getTaxon() != null
246
                && getTaxon().equals(((TaxonEditorInputE4) obj).getTaxon())) {
247
            if (((TaxonEditorInputE4) obj).getInitiallySelectedTaxonBase() != null){
248
                setInitiallySelectedTaxonBase(((TaxonEditorInputE4) obj).getInitiallySelectedTaxonBase());
249
            }
250
            return true;
251
        }
252
        return false;
253
    }
254

    
255
    public Taxon getTaxon(){
256
        if(taxonNode!=null){
257
            Taxon taxon = CdmBase.deproxy(taxonNode.getTaxon(), Taxon.class);
258
            return taxon;
259
        }
260
        return null;
261
    }
262

    
263
    public TaxonNode getTaxonNode() {
264
        return taxonNode;
265
    }
266

    
267
    @Override
268
    public ConversationHolder getConversationHolder() {
269
        return conversation;
270
    }
271

    
272
    /** {@inheritDoc} */
273
    @Override
274
    public void update(CdmDataChangeMap events) {
275
        if(dataChangeBehavior == null){
276
            dataChangeBehavior = new TaxonEditorInputDataChangeBehaviourE4(this);
277
        }
278

    
279
        DataChangeBridge.handleDataChange(events, dataChangeBehavior);
280
    }
281

    
282
    public void setInitiallySelectedTaxonBase(TaxonBase taxonBase) {
283
        this.initiallySelectedTaxonBase = taxonBase;
284
    }
285

    
286
    public TaxonBase getInitiallySelectedTaxonBase() {
287
        return initiallySelectedTaxonBase;
288
    }
289

    
290
    public Set<AbstractPostTaxonOperation> getOperations() {
291
        return operations;
292
    }
293

    
294
    public void setOperations(Set<AbstractPostTaxonOperation> operations) {
295
        this.operations = operations;
296
    }
297

    
298
    public void addOperation(AbstractPostTaxonOperation operation) {
299
        this.operations.add(operation);
300
    }
301

    
302
    public void addToSaveNew(TaxonBase toSaveNew) {
303
        this.toSaveNew.add(toSaveNew);
304
    }
305

    
306
    @Override
307
    public List<TaxonNode> getRootEntities() {
308
        return Arrays.asList(taxonNode);
309
    }
310

    
311
    @Override
312
    public void merge() {
313
        if (!this.getCdmEntitySession().isActive()){
314
            this.getCdmEntitySession().bind();
315
        }
316
        for(Entry<TaxonBase, TaxonBaseDeletionConfigurator> entry:toDelete.entrySet()){
317
            delete(entry.getKey(), entry.getValue());
318
        }
319
        toDelete.clear();
320
        for(AbstractPostOperation entry:operations){
321
            EditorUtil.executeOperation(entry,sync);
322
        }
323
        operations.clear();
324

    
325
        CdmStore.getService(ITaxonService.class).save(toSaveNew);
326

    
327
        CdmStore.getService(ITaxonNodeService.class).merge(taxonNode, true);
328

    
329
    }
330

    
331
    /**
332
     * @param key
333
     * @param value
334
     */
335
    private void delete(TaxonBase key, TaxonBaseDeletionConfigurator value) {
336
        if (key instanceof Synonym){
337
            CdmStore.getService(ITaxonService.class).deleteSynonym(((Synonym)key).getUuid(), (SynonymDeletionConfigurator) value);
338
        }else{
339
            CdmStore.getService(ITaxonService.class).deleteTaxon(((Taxon)key).getUuid(), (TaxonDeletionConfigurator) value, null);
340
        }
341

    
342
    }
343

    
344
    @Override
345
    public Map<Object, List<String>> getPropertyPathsMap() {
346
        return null;
347
    }
348

    
349
    private List<String> getTaxonNodePropertyPaths() {
350
        List<String> taxonNodePropertyPaths = new ArrayList<String>();
351
        for(String propertyPath : getTaxonBasePropertyPaths()) {
352
            taxonNodePropertyPaths.add("taxon." + propertyPath); //$NON-NLS-1$
353
        }
354
        return taxonNodePropertyPaths;
355
    }
356

    
357
    private List<String> getTaxonBasePropertyPaths() {
358
        List<String> taxonBasePropertyPaths = Arrays.asList(new String[] {
359
                "sec", //$NON-NLS-1$
360
                "createdBy", //$NON-NLS-1$
361
                "updatedBy", //$NON-NLS-1$
362
                "annotations", //$NON-NLS-1$
363
                "markers", //$NON-NLS-1$
364
                "credits", //$NON-NLS-1$
365
                "extensions", //$NON-NLS-1$
366
                "rights", //$NON-NLS-1$
367
                "sources", //$NON-NLS-1$
368
                "identifiers",
369
                "descriptions", //$NON-NLS-1$
370
                "relationsToThisTaxon.relatedFrom.name.taxonBases.taxonNodes", //$NON-NLS-1$
371
                "relationsToThisTaxon.relatedFrom.name.taxonBases.relationsFromThisTaxon", //$NON-NLS-1$
372
                "relationsToThisTaxon.relatedFrom.name.taxonBases.relationsToThisTaxon", //$NON-NLS-1$
373
                "relationsFromThisTaxon.relatedTo.name.taxonBases.taxonNodes", //$NON-NLS-1$
374
                "relationsFromThisTaxon.relatedTo.name.taxonBases.relationsFromThisTaxon", //$NON-NLS-1$
375
                "relationsFromThisTaxon.relatedTo.name.taxonBases.relationsToThisTaxon", //$NON-NLS-1$
376
                "taxonNodes", //$NON-NLS-1$
377
                "descriptions.descriptionElements.feature", //$NON-NLS-1$
378
                "descriptions.descriptionElements.area", //$NON-NLS-1$
379
                "descriptions.descriptionElements.status", //$NON-NLS-1$
380
                "descriptions.markers", //$NON-NLS-1$
381
                "name.descriptions", //$NON-NLS-1$
382
                "name.typeDesignations", //$NON-NLS-1$
383
                "name.status", //$NON-NLS-1$
384
                "name.nomenclaturalReference.inReference", //$NON-NLS-1$
385
                "name.taxonBases.taxonNodes", //$NON-NLS-1$
386
                "name.relationsFromThisName", //$NON-NLS-1$
387
                "name.relationsToThisName", //$NON-NLS-1$
388
                "name.homotypicalGroup.typifiedNames.taxonBases.synonyms.synonym.name.status", //$NON-NLS-1$
389
                "name.homotypicalGroup.typifiedNames.relationsToThisName.fromName", //$NON-NLS-1$
390
                "synonyms.name.status.type", //$NON-NLS-1$
391
                "synonyms.name.relationsToThisName.fromName", //$NON-NLS-1$
392
                "synonyms.name.nomenclaturalReference.inReference.authorship", //$NON-NLS-1$
393
                "synonyms.name.nomenclaturalReference.authorship", //$NON-NLS-1$
394
//                "synonyms.name.homotypicalGroup", //$NON-NLS-1$
395
//                "synonyms.synonym.name.homotypicalGroup.typifiedNames", //$NON-NLS-1$
396
                "synonyms.name.homotypicalGroup.typifiedNames.taxonBases.synonyms" //$NON-NLS-1$
397
        });
398

    
399
        return taxonBasePropertyPaths;
400
    }
401

    
402
    /**
403
     * @param selectedElement
404
     * @param deleteConfig
405
     */
406
    public void addTaxonBaseToDelete(TaxonBase selectedElement, TaxonBaseDeletionConfigurator deleteConfig) {
407
        this.toDelete.put(selectedElement, deleteConfig);
408

    
409
    }
410

    
411
}
(2-2/2)