Project

General

Profile

Download (16.7 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.INameService;
28
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
29
import eu.etaxonomy.cdm.api.service.ITaxonService;
30
import eu.etaxonomy.cdm.api.service.config.SynonymDeletionConfigurator;
31
import eu.etaxonomy.cdm.api.service.config.TaxonBaseDeletionConfigurator;
32
import eu.etaxonomy.cdm.api.service.config.TaxonDeletionConfigurator;
33
import eu.etaxonomy.cdm.model.common.CdmBase;
34
import eu.etaxonomy.cdm.model.name.HybridRelationship;
35
import eu.etaxonomy.cdm.model.name.TaxonName;
36
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
37
import eu.etaxonomy.cdm.model.taxon.Synonym;
38
import eu.etaxonomy.cdm.model.taxon.Taxon;
39
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
40
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
41
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
42
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
43
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
44
import eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput;
45
import eu.etaxonomy.taxeditor.editor.ChooseFromMultipleTaxonNodesDialog;
46
import eu.etaxonomy.taxeditor.editor.EditorUtil;
47
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
48
import eu.etaxonomy.taxeditor.model.DataChangeBridge;
49
import eu.etaxonomy.taxeditor.model.MessagingUtils;
50
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
51
import eu.etaxonomy.taxeditor.operation.AbstractPostTaxonOperation;
52
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
53
import eu.etaxonomy.taxeditor.store.CdmStore;
54

    
55

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

    
64
    private static final String INCORRECT_STATE = Messages.TaxonEditorInput_INCORRECT_STATE;
65

    
66
    private final ConversationHolder conversation;
67

    
68
    private TaxonNode taxonNode;
69

    
70
    private Map<TaxonBase, TaxonBaseDeletionConfigurator> toDelete = new HashMap<>();
71
    private Set<Synonym> toSaveNewSynonym = new HashSet<>();
72
    private Set<TaxonBase> toSaveNewConcept = new HashSet<>();
73
    private Set<TaxonName> toSaveNewName = new HashSet<>();
74

    
75

    
76
    private Set<AbstractPostTaxonOperation> operations = new HashSet<>();
77

    
78
    private TaxonEditorInputDataChangeBehaviourE4 dataChangeBehavior;
79

    
80
    private TaxonBase initiallySelectedTaxonBase;
81

    
82
    UISynchronize sync;
83

    
84

    
85
    public void setSync(UISynchronize sync) {
86
        this.sync = sync;
87
    }
88

    
89
    private enum CdmType {
90
        TAXON_NODE,
91
        TAXON_BASE,
92
        PARENT_TAXON_NODE
93
    }
94

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

    
111
    private void init(TaxonNode taxonNode) {
112
    	this.taxonNode = taxonNode;
113
    }
114

    
115

    
116
    private void initForTaxonNode(UUID taxonNodeUuid) {
117
    	this.getCdmEntitySession().bind();
118
        TaxonNode taxonNode = CdmStore.getService(ITaxonNodeService.class).load(taxonNodeUuid, getTaxonNodePropertyPaths());
119
        if(taxonNode == null){
120
            MessagingUtils.warningDialog(Messages.TaxonEditorInput_NOT_IMPLEMENTED, TaxonEditorInputE4.class, Messages.TaxonEditorInput_NOT_IMPLEMENTED_MESSAGE);
121
        }
122
        init(taxonNode);
123
        setInitiallySelectedTaxonBase(getTaxon());
124

    
125
    }
126

    
127
    private void initForTaxonBase(UUID taxonBaseUuid) {
128
    	this.getCdmEntitySession().bind();
129
        TaxonBase taxonBase = CdmStore.getService(ITaxonService.class).load(taxonBaseUuid, getTaxonBasePropertyPaths());
130
        if (taxonBase != null){
131
            if(taxonBase.isInstanceOf(Taxon.class)){
132
                Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
133
                setInitiallySelectedTaxonBase(taxon);
134

    
135
                if (taxon.getTaxonNodes().size() == 0 && taxon.isMisapplication()){
136
                    // TODO get accepted taxon
137
                    MessagingUtils.info(Messages.TaxonEditorInput_OPEN_MISSAPPLIED_NAME);
138

    
139
                    Set<Taxon> acceptedTaxa = new HashSet<Taxon>();
140
                    Set<TaxonRelationship> relations = taxon.getRelationsFromThisTaxon();
141
                    for(TaxonRelationship relation : relations){
142
                        if(relation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){
143
                            acceptedTaxa.add(relation.getToTaxon());
144
                        }
145
                    }
146
                    setInputForMultipleTaxa(conversation, acceptedTaxa);
147

    
148
                }else{
149
                    setInputForMultipleNodes(conversation, taxon.getTaxonNodes());
150
                }
151
            }else if(taxonBase instanceof Synonym){
152
                Synonym synonym = (Synonym) taxonBase;
153

    
154
                Set<Taxon> taxa = new HashSet<>();
155
                Taxon taxon = synonym.getAcceptedTaxon();
156
                if (taxon != null){
157
                	taxa.add(taxon);
158
                }
159
                setInputForMultipleTaxa(conversation, taxa);
160
                setInitiallySelectedTaxonBase(synonym);
161
            }
162
        }
163
    }
164

    
165

    
166
    private void initForParentTaxonNode(UUID parentNodeUuid){
167
    	this.getCdmEntitySession().bind();
168
        TaxonName name = PreferencesUtil.getPreferredNomenclaturalCode().getNewTaxonNameInstance(null);
169
        ITaxonTreeNode parentNode = CdmStore.getService(IClassificationService.class).getTreeNodeByUuid(parentNodeUuid);
170

    
171
        Taxon newTaxon = Taxon.NewInstance(name, parentNode.getReference());
172
        TaxonNode newTaxonNode = parentNode.addChildTaxon(newTaxon, parentNode.getReference(), parentNode.getMicroReference());
173

    
174
        // add the new taxon to the editors persistence context
175
        UUID newTaxonNodeUuid = CdmStore.getService(ITaxonNodeService.class).save(newTaxonNode).getUuid();
176

    
177
        initForTaxonNode(newTaxonNodeUuid);
178
    }
179

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

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

    
214
    public static TaxonEditorInputE4 NewInstance(UUID taxonNodeUuid) {
215
        return new TaxonEditorInputE4(taxonNodeUuid, CdmType.TAXON_NODE);
216

    
217
    }
218

    
219
    public static TaxonEditorInputE4 NewInstanceFromTaxonBase(UUID taxonBaseUuid){
220
        return new TaxonEditorInputE4(taxonBaseUuid, CdmType.TAXON_BASE);
221
    }
222

    
223

    
224
    public static TaxonEditorInputE4 NewEmptyInstance(UUID parentNodeUuid){
225
        return new TaxonEditorInputE4(parentNodeUuid, CdmType.PARENT_TAXON_NODE);
226
    }
227

    
228
    public Object getAdapter(Class adapter) {
229

    
230
        if (adapter == Taxon.class) {
231
            return getTaxon();
232
        }
233

    
234
        if (adapter == TaxonNode.class) {
235
            return taxonNode;
236
        }
237

    
238
        return null;
239
    }
240

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

    
260
    public Taxon getTaxon(){
261
        if(taxonNode!=null){
262
            Taxon taxon = CdmBase.deproxy(taxonNode.getTaxon(), Taxon.class);
263
            return taxon;
264
        }
265
        return null;
266
    }
267

    
268
    public TaxonNode getTaxonNode() {
269
        return taxonNode;
270
    }
271

    
272
    @Override
273
    public ConversationHolder getConversationHolder() {
274
        return conversation;
275
    }
276

    
277
    /** {@inheritDoc} */
278
    @Override
279
    public void update(CdmDataChangeMap events) {
280
        if(dataChangeBehavior == null){
281
            dataChangeBehavior = new TaxonEditorInputDataChangeBehaviourE4(this);
282
        }
283

    
284
        DataChangeBridge.handleDataChange(events, dataChangeBehavior);
285
    }
286

    
287
    public void setInitiallySelectedTaxonBase(TaxonBase taxonBase) {
288
        this.initiallySelectedTaxonBase = taxonBase;
289
    }
290

    
291
    public TaxonBase getInitiallySelectedTaxonBase() {
292
        return initiallySelectedTaxonBase;
293
    }
294

    
295
    public Set<AbstractPostTaxonOperation> getOperations() {
296
        return operations;
297
    }
298

    
299
    public void setOperations(Set<AbstractPostTaxonOperation> operations) {
300
        this.operations = operations;
301
    }
302

    
303
    public void addOperation(AbstractPostTaxonOperation operation) {
304
        this.operations.add(operation);
305
    }
306

    
307
    public void addToSaveNewSynonym(Synonym toSaveNew) {
308
        this.toSaveNewSynonym.add(toSaveNew);
309
    }
310
    public void addToSaveNewConcept(Taxon toSaveNew) {
311
        this.toSaveNewConcept.add(toSaveNew);
312
    }
313

    
314
    @Override
315
    public List<TaxonNode> getRootEntities() {
316
        return Arrays.asList(taxonNode);
317
    }
318

    
319
    @Override
320
    public void merge() {
321
        if (!this.getCdmEntitySession().isActive()){
322
            this.getCdmEntitySession().bind();
323
        }
324
        for(Entry<TaxonBase, TaxonBaseDeletionConfigurator> entry:toDelete.entrySet()){
325
            delete(entry.getKey(), entry.getValue());
326
        }
327
        toDelete.clear();
328
        for(AbstractPostOperation entry:operations){
329
            EditorUtil.executeOperation(entry,sync);
330
        }
331
        operations.clear();
332

    
333
        for (Synonym syn: toSaveNewSynonym){
334
            for (HybridRelationship rel : syn.getName().getHybridChildRelations()){
335
                if (!rel.getParentName().isPersited()) {
336
                    toSaveNewName.add(rel.getParentName());
337
                }
338
                if (!rel.getHybridName().isPersited()) {
339
                    toSaveNewName.add(rel.getHybridName());
340
                }
341

    
342
            }
343
        }
344

    
345
        for (TaxonBase concept: toSaveNewConcept){
346
            for (HybridRelationship rel : concept.getName().getHybridChildRelations()){
347
                if (!rel.getParentName().isPersited()) {
348
                    toSaveNewName.add(rel.getParentName());
349
                }
350
                if (!rel.getHybridName().isPersited()) {
351
                    toSaveNewName.add(rel.getHybridName());
352
                }
353

    
354
            }
355
        }
356
        CdmStore.getService(INameService.class).save(toSaveNewName);
357
        CdmStore.getService(ITaxonService.class).save(toSaveNewConcept);
358

    
359
        toSaveNewName.clear();
360
        toSaveNewConcept.clear();
361

    
362
        CdmStore.getService(ITaxonNodeService.class).merge(taxonNode, true);
363

    
364
    }
365

    
366
    /**
367
     * @param key
368
     * @param value
369
     */
370
    private void delete(TaxonBase key, TaxonBaseDeletionConfigurator value) {
371
        if (key instanceof Synonym){
372
            CdmStore.getService(ITaxonService.class).deleteSynonym(((Synonym)key).getUuid(), (SynonymDeletionConfigurator) value);
373
        }else{
374
            CdmStore.getService(ITaxonService.class).deleteTaxon(((Taxon)key).getUuid(), (TaxonDeletionConfigurator) value, null);
375
        }
376

    
377
    }
378

    
379
    @Override
380
    public Map<Object, List<String>> getPropertyPathsMap() {
381
        return null;
382
    }
383

    
384
    private List<String> getTaxonNodePropertyPaths() {
385
        List<String> taxonNodePropertyPaths = new ArrayList<String>();
386
        for(String propertyPath : getTaxonBasePropertyPaths()) {
387
            taxonNodePropertyPaths.add("taxon." + propertyPath); //$NON-NLS-1$
388
        }
389
        return taxonNodePropertyPaths;
390
    }
391

    
392
    private List<String> getTaxonBasePropertyPaths() {
393
        List<String> taxonBasePropertyPaths = Arrays.asList(new String[] {
394
                "sec", //$NON-NLS-1$
395
                "createdBy", //$NON-NLS-1$
396
                "updatedBy", //$NON-NLS-1$
397
                "annotations", //$NON-NLS-1$
398
                "markers", //$NON-NLS-1$
399
                "credits", //$NON-NLS-1$
400
                "extensions", //$NON-NLS-1$
401
                "rights", //$NON-NLS-1$
402
                "sources", //$NON-NLS-1$
403
                "identifiers",
404
                "descriptions", //$NON-NLS-1$
405
                "relationsToThisTaxon.relatedFrom.name.taxonBases.taxonNodes", //$NON-NLS-1$
406
                "relationsToThisTaxon.relatedFrom.name.taxonBases.relationsFromThisTaxon", //$NON-NLS-1$
407
                "relationsToThisTaxon.relatedFrom.name.taxonBases.relationsToThisTaxon", //$NON-NLS-1$
408
                "relationsFromThisTaxon.relatedTo.name.taxonBases.taxonNodes", //$NON-NLS-1$
409
                "relationsFromThisTaxon.relatedTo.name.taxonBases.relationsFromThisTaxon", //$NON-NLS-1$
410
                "relationsFromThisTaxon.relatedTo.name.taxonBases.relationsToThisTaxon", //$NON-NLS-1$
411
                "taxonNodes", //$NON-NLS-1$
412
                "descriptions.descriptionElements.feature", //$NON-NLS-1$
413
                "descriptions.descriptionElements.area", //$NON-NLS-1$
414
                "descriptions.descriptionElements.status", //$NON-NLS-1$
415
                "descriptions.markers", //$NON-NLS-1$
416
                "name.descriptions", //$NON-NLS-1$
417
                "name.typeDesignations", //$NON-NLS-1$
418
                "name.status", //$NON-NLS-1$
419
                "name.nomenclaturalReference.inReference", //$NON-NLS-1$
420
                "name.taxonBases.taxonNodes", //$NON-NLS-1$
421
                "name.relationsFromThisName", //$NON-NLS-1$
422
                "name.relationsToThisName", //$NON-NLS-1$
423
                "name.homotypicalGroup.typifiedNames.taxonBases.synonyms.synonym.name.status", //$NON-NLS-1$
424
                "name.homotypicalGroup.typifiedNames.relationsToThisName.fromName", //$NON-NLS-1$
425
                "synonyms.name.status.type", //$NON-NLS-1$
426
                "synonyms.name.relationsToThisName.fromName", //$NON-NLS-1$
427
                "synonyms.name.nomenclaturalReference.inReference.authorship", //$NON-NLS-1$
428
                "synonyms.name.nomenclaturalReference.authorship", //$NON-NLS-1$
429
//                "synonyms.name.homotypicalGroup", //$NON-NLS-1$
430
//                "synonyms.synonym.name.homotypicalGroup.typifiedNames", //$NON-NLS-1$
431
                "synonyms.name.homotypicalGroup.typifiedNames.taxonBases.synonyms" //$NON-NLS-1$
432
        });
433

    
434
        return taxonBasePropertyPaths;
435
    }
436

    
437
    /**
438
     * @param selectedElement
439
     * @param deleteConfig
440
     */
441
    public void addTaxonBaseToDelete(TaxonBase selectedElement, TaxonBaseDeletionConfigurator deleteConfig) {
442
        this.toDelete.put(selectedElement, deleteConfig);
443

    
444
    }
445

    
446
    /**
447
     * @param newName
448
     */
449
    public void addToSaveNewName(TaxonName newName) {
450
        this.toSaveNewName.add(newName);
451
    }
452

    
453
}
(2-2/2)