Project

General

Profile

Download (11.3 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2017 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
package eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix;
10

    
11
import java.util.Arrays;
12
import java.util.Collection;
13
import java.util.Collections;
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.UUID;
18
import java.util.stream.Collectors;
19

    
20
import javax.annotation.PostConstruct;
21
import javax.annotation.PreDestroy;
22
import javax.inject.Inject;
23

    
24
import org.eclipse.core.runtime.IProgressMonitor;
25
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
26
import org.eclipse.e4.core.contexts.IEclipseContext;
27
import org.eclipse.e4.ui.di.Focus;
28
import org.eclipse.e4.ui.di.Persist;
29
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
30
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
31
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
32
import org.eclipse.jface.viewers.IStructuredSelection;
33
import org.eclipse.nebula.widgets.nattable.NatTable;
34
import org.eclipse.swt.SWT;
35
import org.eclipse.swt.custom.StackLayout;
36
import org.eclipse.swt.widgets.Composite;
37
import org.eclipse.swt.widgets.Label;
38

    
39
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
40
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
41
import eu.etaxonomy.cdm.api.service.DeleteResult;
42
import eu.etaxonomy.cdm.api.service.IDescriptionService;
43
import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
44
import eu.etaxonomy.cdm.api.service.config.RemoveDescriptionsFromDescriptiveDataSetConfigurator;
45
import eu.etaxonomy.cdm.api.service.dto.DescriptionBaseDto;
46
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
47
import eu.etaxonomy.cdm.api.service.dto.SpecimenRowWrapperDTO;
48
import eu.etaxonomy.cdm.model.description.DescriptionBase;
49
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
50
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
51
import eu.etaxonomy.cdm.model.term.TermType;
52
import eu.etaxonomy.cdm.persistence.dto.MergeResult;
53
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
54
import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
55
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
56
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
57
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
58
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
59
import eu.etaxonomy.taxeditor.model.MessagingUtils;
60
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
61
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
62
import eu.etaxonomy.taxeditor.store.CdmStore;
63
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
64

    
65
/**
66
 * Character matrix editor for editing specimen/taxon descriptions in a table
67
 * @author pplitzner
68
 * @since Nov 26, 2017
69
 *
70
 */
71
public class CharacterMatrixPart implements IE4SavablePart, IConversationEnabled, IDirtyMarkable,
72
ICdmEntitySessionEnabled, IPartContentHasSupplementalData, IPartContentHasDetails{
73

    
74
    private static final List<String> WS_PROPERTY_PATH = Arrays.asList(new String[] {
75
            "descriptions", //$NON-NLS-1$
76
            "descriptions.describedSpecimenOrObservation", //$NON-NLS-1$
77
            "descriptions.describedSpecimenOrObservation.gatheringEvent", //$NON-NLS-1$
78
            "descriptions.describedSpecimenOrObservation.gatheringEvent.actor", //$NON-NLS-1$
79
            "descriptions.descriptionElements", //$NON-NLS-1$
80
            "descriptions.descriptionElements.stateData", //$NON-NLS-1$
81
            "descriptions.descriptionElements.stateData.state", //$NON-NLS-1$
82
            "descriptions.descriptionElements.inDescription", //$NON-NLS-1$
83
            "descriptions.descriptionElements.inDescription.descriptionElements", //$NON-NLS-1$
84
            "descriptions.descriptionElements.feature", //$NON-NLS-1$
85
            "representations", //$NON-NLS-1$
86
            "descriptiveSystem", //$NON-NLS-1$
87
            "taxonSubtreeFilter", //$NON-NLS-1$
88
            "taxonSubtreeFilter.parent", //$NON-NLS-1$
89
            "taxonSubtreeFilter.classification", //$NON-NLS-1$
90
            "taxonSubtreeFilter.taxon", //$NON-NLS-1$
91
            "taxonSubtreeFilter.taxon.name", //$NON-NLS-1$
92
            "taxonSubtreeFilter.taxon.name.rank", //$NON-NLS-1$
93
            "geoFilter", //$NON-NLS-1$
94
            "minRank", //$NON-NLS-1$
95
            "maxRank", //$NON-NLS-1$
96
    });
97

    
98
    private DescriptiveDataSet descriptiveDataSet;
99

    
100
    private ConversationHolder conversation;
101

    
102
    private ICdmEntitySession cdmEntitySession;
103

    
104
    @Inject
105
    private ESelectionService selService;
106

    
107
    @Inject
108
    private MDirtyable dirty;
109

    
110
    @Inject
111
    private MPart thisPart;
112

    
113
    private CharacterMatrix matrix;
114

    
115
    private StackLayout stackLayout;
116

    
117
    private Label label;
118

    
119
    @PostConstruct
120
    public void create(Composite parent, IEclipseContext context) {
121
        if(CdmStore.isActive() && conversation==null){
122
            conversation = CdmStore.createConversation();
123
        }
124
        if(cdmEntitySession == null){
125
            cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
126
            cdmEntitySession.bind();
127
        }
128
        else{
129
            return;
130
        }
131
        stackLayout = new StackLayout();
132
        parent.setLayout(stackLayout);
133
        matrix = new CharacterMatrix(parent, this);
134
        label = new Label(parent, SWT.NONE);
135
        label.setText(Messages.CharacterMatrixPart_LOADING_MATRIX);
136
        stackLayout.topControl = label;
137
        ContextInjectionFactory.inject(matrix, context);
138
    }
139

    
140
    public void init(UUID descriptiveDataSetUuid, boolean treeView) {
141
        this.descriptiveDataSet = CdmStore.getService(IDescriptiveDataSetService.class).load(descriptiveDataSetUuid, WS_PROPERTY_PATH);
142
        if(descriptiveDataSet!=null){
143
            if(descriptiveDataSet.getDescriptiveSystem()==null
144
                    || descriptiveDataSet.getDescriptiveSystem().getTermType()==null
145
                    || !descriptiveDataSet.getDescriptiveSystem().getTermType().equals(TermType.Character)){
146
                MessagingUtils.informationDialog(Messages.CharacterMatrixPart_COULD_NOT_OPEN, Messages.CharacterMatrixPart_COULD_NOT_OPEN_MESSAGE);
147
                loadingFailed();
148
                return;
149
            }
150
            try {
151
                matrix.initDescriptiveDataSet();
152
            } catch (IllegalArgumentException e) {
153
                MessagingUtils.errorDialog("Error during initilization", this, "Could not load matrix", TaxeditorEditorPlugin.PLUGIN_ID, e, false);
154
                loadingFailed();
155
                return;
156
            }
157
            matrix.createTable(treeView, true, true);
158
            thisPart.setLabel(descriptiveDataSet.getLabel());
159
            matrix.loadDescriptions( true, true);
160
        }
161
    }
162

    
163
    public IStructuredSelection getSelection(){
164
        return matrix.getSelection();
165
    }
166

    
167
    public void setDirty() {
168
        this.dirty.setDirty(true);
169
    }
170

    
171
    public DescriptiveDataSet getDescriptiveDataSet() {
172
        return descriptiveDataSet;
173
    }
174

    
175
    public void setDescriptiveDataSet(DescriptiveDataSet dataSet) {
176
        this.descriptiveDataSet = dataSet;
177
    }
178

    
179
    public NatTable getNatTable() {
180
        return matrix.getNatTable();
181
    }
182

    
183
    public ESelectionService getSelectionService() {
184
        return selService;
185
    }
186

    
187
    public CharacterMatrix getMatrix() {
188
        return matrix;
189
    }
190

    
191
    @Persist
192
    @Override
193
    public void save(IProgressMonitor monitor) {
194
        // save edited descriptions
195
        List<DescriptionBaseDto> descriptions = matrix.getRowsToMerge().values().stream()
196
        .map(row->row.getDescription())
197
        .collect(Collectors.toList());
198
        matrix.addSpecimensToDescriptiveDataSet();
199
        //newly added descriptions should not be saved again.
200
//        descriptions.removeAll(matrix.getRowsToSave().values());
201
        matrix.getRowsToMerge().clear();
202
        if (matrix.getDescriptionsToDelete() != null && !matrix.getDescriptionsToDelete().isEmpty()){
203
            DeleteResult result = new DeleteResult();
204
            for (RemoveDescriptionsFromDescriptiveDataSetConfigurator config: matrix.getDescriptionsToDelete().keySet()){
205
               result.includeResult(CdmStore.getService(IDescriptiveDataSetService.class).removeDescriptions(matrix.getDescriptionsToDelete().get(config), matrix.getDescriptiveDataSet().getUuid(), config));
206
            }
207
            matrix.getDescriptionsToDelete().clear();
208
        }
209
        List<MergeResult<DescriptionBase>> results = CdmStore.getService(IDescriptionService.class).mergeDescriptions(descriptions, matrix.getDescriptiveDataSet().getUuid(), true);
210
        conversation.commit();
211
        HashMap<UUID, DescriptionBase> descriptionResults = new HashMap<>();
212
        for (MergeResult result: results){
213
            if (result.getMergedEntity() != null){
214
                descriptionResults.put(result.getMergedEntity().getUuid(), (DescriptionBase)result.getMergedEntity());
215
            }
216
        }
217
        List<Object> updateRows = matrix.getDescriptions().stream().filter(row->descriptionResults.keySet().contains(((RowWrapperDTO)row).getDescription().getDescription().getUuid())).collect(Collectors.toList());
218
        for (Object updateRow: updateRows){
219
            if (updateRow instanceof SpecimenRowWrapperDTO){
220
                SpecimenRowWrapperDTO dto = (SpecimenRowWrapperDTO)updateRow;
221
                dto.getDescription().setDescription(descriptionResults.get(((SpecimenRowWrapperDTO) updateRow).getDescription().getDescription().getUuid()));
222
            }
223
        }
224
//        matrix.loadDescriptions(getDescriptiveDataSet().getUuid(), false);
225

    
226
        dirty.setDirty(false);
227
    }
228

    
229
    @Override
230
    public boolean isDirty() {
231
        return dirty.isDirty();
232
    }
233

    
234
    @Focus
235
    public void setFocus(){
236
        if(conversation!=null){
237
            conversation.bind();
238
        }
239
        if(cdmEntitySession != null) {
240
            cdmEntitySession.bind();
241
        }
242
    }
243

    
244
    @PreDestroy
245
    public void dispose(){
246
        if (conversation != null) {
247
            conversation.close();
248
            conversation = null;
249
        }
250
        if(cdmEntitySession != null) {
251
            cdmEntitySession.dispose();
252
            cdmEntitySession = null;
253
        }
254
        dirty.setDirty(false);
255
    }
256

    
257
    @Override
258
    public void update(CdmDataChangeMap arg0) {
259
    }
260

    
261
    @Override
262
    public ConversationHolder getConversationHolder() {
263
        return conversation;
264
    }
265

    
266
    @Override
267
    public void changed(Object element) {
268
        setDirty();
269
        matrix.getNatTable().refresh();
270
    }
271

    
272
    @Override
273
    public void forceDirty() {
274
        setDirty();
275
    }
276

    
277
    @Override
278
    public ICdmEntitySession getCdmEntitySession() {
279
        return cdmEntitySession;
280
    }
281

    
282
    @Override
283
    public Collection<DescriptiveDataSet> getRootEntities() {
284
        return Collections.singleton(this.descriptiveDataSet);
285
    }
286

    
287
    @Override
288
    public Map<Object, List<String>> getPropertyPathsMap() {
289
        Map<Object, List<String>> propertyMap = new HashMap<>();
290
        propertyMap.put(SpecimenOrObservationBase.class,WS_PROPERTY_PATH);
291
        return propertyMap;
292
    }
293

    
294
    private void loadingFailed() {
295
        label.setText(Messages.CharacterMatrixPart_LOADING_MATRIX_FAILED);
296
    }
297

    
298
    void loadingDone() {
299
        stackLayout.topControl = matrix;
300
        matrix.getParent().layout();
301
    }
302

    
303
}
(9-9/19)