Project

General

Profile

Download (15.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2018 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.ArrayList;
12
import java.util.Collection;
13
import java.util.List;
14
import java.util.Set;
15
import java.util.UUID;
16
import java.util.stream.Collectors;
17

    
18
import org.eclipse.core.runtime.ICoreRunnable;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.SubMonitor;
21
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
22
import org.eclipse.core.runtime.jobs.Job;
23
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
24
import org.eclipse.jface.layout.GridDataFactory;
25
import org.eclipse.jface.viewers.IStructuredSelection;
26
import org.eclipse.jface.window.Window;
27
import org.eclipse.jface.wizard.WizardDialog;
28
import org.eclipse.swt.SWT;
29
import org.eclipse.swt.events.SelectionAdapter;
30
import org.eclipse.swt.events.SelectionEvent;
31
import org.eclipse.swt.layout.RowLayout;
32
import org.eclipse.swt.widgets.Button;
33
import org.eclipse.swt.widgets.Composite;
34

    
35
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
36
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
37
import eu.etaxonomy.cdm.api.service.UpdateResult;
38
import eu.etaxonomy.cdm.api.service.description.AggregationMode;
39
import eu.etaxonomy.cdm.api.service.description.StructuredDescriptionAggregationConfiguration;
40
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
41
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
42
import eu.etaxonomy.cdm.filter.TaxonNodeFilter;
43
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
44
import eu.etaxonomy.cdm.model.location.NamedArea;
45
import eu.etaxonomy.cdm.model.taxon.Taxon;
46
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
47
import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
48
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
49
import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
50
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
51
import eu.etaxonomy.taxeditor.model.ImageResources;
52
import eu.etaxonomy.taxeditor.model.MessagingUtils;
53
import eu.etaxonomy.taxeditor.store.CdmStore;
54
import eu.etaxonomy.taxeditor.store.StoreUtil;
55
import eu.etaxonomy.taxeditor.ui.dialog.configurator.StructuredAggregationConfigurationWizard;
56
import eu.etaxonomy.taxeditor.ui.dialog.selection.TaxonSelectionDialog;
57

    
58
/**
59
 * @author pplitzner
60
 * @since Jul 9, 2018
61
 */
62
public class CharacterMatrixBottomToolbar extends Composite{
63

    
64
    private CharacterMatrix matrix;
65

    
66
    public CharacterMatrixBottomToolbar(CharacterMatrix matrix, int style) {
67
        super(matrix, style);
68
        this.matrix = matrix;
69

    
70
        init();
71
    }
72

    
73
    private void init() {
74

    
75
        setLayout(new RowLayout());
76
        GridDataFactory.fillDefaults().grab(true, false).applyTo(this);
77

    
78
        /**
79
         * Add description button
80
         */
81
        Button btnAddDescription = new Button(this, SWT.PUSH);
82
        btnAddDescription.setImage(ImageResources.getImage(ImageResources.ADD_ICON_GREEN));
83
        btnAddDescription.addSelectionListener(new SelectionAdapter() {
84
            @Override
85
            public void widgetSelected(SelectionEvent e) {
86
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
87
                    return;
88
                }
89
                SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(matrix.getShell(), matrix);
90
                if(dialog.open()==Window.OK){
91
                    Collection<SpecimenNodeWrapper> wrappers = dialog.getSpecimen();
92
                    if(wrappers.stream().anyMatch(wrapper->wrapper.getTaxonDescriptionUuid()==null)
93
                            && !MessagingUtils.confirmDialog(
94
                                    "Create Taxon Association",
95
                                    "Some specimens are not linked with taxon via IndividualsAssociation yet.\n"
96
                                    + "Do you want to create this association?")){
97
                        return;
98
                    }
99
                    addRowsToMatrix(wrappers, matrix.getDescriptiveDataSet().getUuid());
100
                    wrappers.forEach(wrapper->matrix.getSpecimenCache().remove(wrapper));
101
                }
102
            }
103
        });
104
        /**
105
         * Remove description button
106
         */
107
        Button btnRemoveDescription = new Button(this, SWT.PUSH);
108
        btnRemoveDescription.setImage(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON));
109
        btnRemoveDescription.addSelectionListener(new SelectionAdapter() {
110
            @Override
111
            public void widgetSelected(SelectionEvent e) {
112
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
113
                    return;
114
                }
115
                if(!MessagingUtils.confirmDialog(Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_TITLE, Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_MESSAGE)){
116
                    return;
117
                }
118
                int[] fullySelectedRowPositions = matrix.getBodyLayer().getSelectionLayer().getFullySelectedRowPositions();
119
                List<RowWrapperDTO> toRemove = new ArrayList<>();
120
                for (int i : fullySelectedRowPositions) {
121
                    Object rowObject = matrix.getBodyDataProvider().getRowObject(i);
122
                    if(rowObject instanceof RowWrapperDTO){
123
                        toRemove.add((RowWrapperDTO) rowObject);
124
                    }
125
                }
126
                toRemove.forEach(rowToRemove -> {
127
                    matrix.putDescriptionToDelete(rowToRemove.getDescription().getUuid());
128
                    matrix.getDescriptions().remove(rowToRemove);
129

    
130
//                    CdmStore.getService(IDescriptiveDataSetService.class).removeDescription(
131
//                            rowToRemove.getDescription().getUuid(), matrix.getDescriptiveDataSet().getUuid());
132
                });
133
            }
134
        });
135
        /**
136
         * Aggregate button
137
         */
138
        Button btnAggregate = new Button(this, SWT.PUSH);
139
        btnAggregate.setText(Messages.CharacterMatrixBottomToolbar_AGGREGATE);
140
        btnAggregate.addSelectionListener(new SelectionAdapter() {
141
            @Override
142
            public void widgetSelected(SelectionEvent e) {
143
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
144
                    return;
145
                }
146
                aggregatDescriptiveDataSet(matrix.getDescriptiveDataSet().getUuid());
147
            }
148
        });
149
        /**
150
         * Key generation button
151
         */
152
        Button btnGenerateKey = new Button(this, SWT.PUSH);
153
        btnGenerateKey.setText("Generate Polytomous Key");
154
        btnGenerateKey.addSelectionListener(new SelectionAdapter() {
155
            @Override
156
            public void widgetSelected(SelectionEvent e) {
157
                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
158
                    return;
159
                }
160
                Set<TaxonNodeDto> nodeDtos = matrix.getDescriptiveDataSet().getTaxonSubtreeFilter().stream()
161
                        .map(node->new TaxonNodeDto(node))
162
                        .collect(Collectors.toSet());
163
                TaxonNodeDto parentDto = CdmStore.getService(ITaxonNodeService.class).findCommonParentDto(nodeDtos);
164
                UUID taxonUuid = parentDto.getTaxonUuid();
165
                int response = MessagingUtils.confirmDialog(
166
                        "Choose taxonomic scope",
167
                        String.format("The common parent taxon of this data set is :\n%s\n\n"
168
                                + "Do you want to use this as the taxonomic scope for the polytomous key?"
169
                                , parentDto.getTaxonTitleCache()), "Yes", "Choose different taxon", "Cancel");
170
                if(response==2){
171
                    return;
172
                }
173
                else if(response==1){
174
                    Taxon taxon = TaxonSelectionDialog.selectTaxon(getShell(), null);
175
                    if(taxon==null){
176
                        return;
177
                    }
178
                    taxonUuid = taxon.getUuid();
179
                }
180
                generateKey(matrix.getDescriptiveDataSet().getUuid(), taxonUuid);
181
            }
182

    
183
        });
184
    }
185

    
186
    private void aggregatDescriptiveDataSet(UUID descriptiveDataSetUuid){
187
        // FIXME: set taxon node filter for config (this is still not used in the aggregation)
188
        StructuredDescriptionAggregationConfiguration config = StructuredDescriptionAggregationConfiguration.NewInstance(
189
                null, null);
190
        IStructuredSelection sel = matrix.getSelection();
191
        Object o = sel.getFirstElement();
192
        TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(matrix.getDescriptiveDataSet().getMinRank(),
193
                matrix.getDescriptiveDataSet().getMaxRank());
194
        for (NamedArea namedArea : matrix.getDescriptiveDataSet().getGeoFilter()) {
195
            filter = filter.orArea(namedArea.getUuid());
196
        }
197
//        for (TaxonNode taxonNode : matrix.getDescriptiveDataSet().getTaxonSubtreeFilter()) {
198
//            filter = filter.orSubtree(taxonNode);
199
//        }
200

    
201
        if (o instanceof TaxonNodeDto){
202
            filter = filter.orSubtree(CdmStore.getService(ITaxonNodeService.class).load(((TaxonNodeDto)o).getUuid()));
203
        }else{
204
            for (TaxonNode taxonNode : matrix.getDescriptiveDataSet().getTaxonSubtreeFilter()) {
205
                filter = filter.orSubtree(taxonNode);
206
            }
207
        }
208
        config.setTaxonNodeFilter(filter);
209

    
210
        config.setDatasetUuid(matrix.getDescriptiveDataSet().getUuid());
211
        config.setAggregateToHigherRanks(true);
212
        config.setAggregationMode(AggregationMode.byAreasAndRanks());
213
        config.setAdaptBatchSize(false);
214
        StructuredAggregationConfigurationWizard aggregationWizard = new StructuredAggregationConfigurationWizard(config, this.matrix.getDescriptiveDataSet());
215
        WizardDialog dialog = new WizardDialog(StoreUtil.getShell(),
216
                aggregationWizard);
217

    
218
        int open = dialog.open();
219
        if (open != Window.OK){
220
            return;
221
        }
222
        UUID monitorUuid =  CdmApplicationState.getLongRunningTasksService().invoke(config);
223

    
224
        String jobLabel = "Aggregate Descriptive Data Set";
225
        Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
226
            SubMonitor subMonitor = SubMonitor.convert(monitor);
227
            subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
228
            IRemotingProgressMonitor remotingMonitor;
229
            try {
230
                remotingMonitor = CdmStore.getProgressMonitorClientManager()
231
                        .pollMonitor(jobLabel,
232
                                monitorUuid,
233
                                50,
234
                                null,
235
                                (List)null,
236
                                subMonitor);
237
                Object resultObject = remotingMonitor.getResult();
238
                if(resultObject instanceof Exception){
239
                    MessagingUtils.errorDialog("Aggregation failed", this, "Aggregation was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
240
                }
241
                else if(resultObject instanceof UpdateResult){
242
                    DescriptiveDataSet dataSet = (DescriptiveDataSet) ((UpdateResult) resultObject).getCdmEntity();
243
                    dataSet = matrix.getCdmEntitiySession().load(dataSet, true);
244
                    // update local dataset
245
                    matrix.setDescriptiveDataSet(dataSet);
246
                    matrix.loadDescriptions(descriptiveDataSetUuid, false);
247
                }
248
            } catch (InterruptedException e) {
249
                return;
250
            }
251
            monitor.done();
252
        });
253
        job.addJobChangeListener(new JobChangeAdapter(){
254
            @Override
255
            public void done(IJobChangeEvent event) {
256
                CharacterMatrixBottomToolbar.this.getDisplay().asyncExec(()->{
257
                    matrix.redraw();
258
                });
259
            }
260
        });
261
        job.schedule();
262
    }
263

    
264
    private void addRowsToMatrix(Collection<SpecimenNodeWrapper> wrappers, UUID descriptiveDataSetUuid){
265
        UUID monitorUuid =  CdmApplicationState.getLongRunningTasksService().addRowWrapperToDataset(wrappers, descriptiveDataSetUuid);
266

    
267
        String jobLabel = "Add specimens to matrix";
268
        Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
269
            SubMonitor subMonitor = SubMonitor.convert(monitor);
270
            subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
271
            IRemotingProgressMonitor remotingMonitor;
272
            try {
273
                remotingMonitor = CdmStore.getProgressMonitorClientManager()
274
                        .pollMonitor(jobLabel,
275
                                monitorUuid,
276
                                50,
277
                                null,
278
                                (List)null,
279
                                subMonitor);
280
                Object resultObject = remotingMonitor.getResult();
281
                if(resultObject instanceof Exception){
282
                    MessagingUtils.errorDialog("Adding specimens failed", this, "Adding specimens was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
283
                }
284
                else if(resultObject instanceof UpdateResult){
285
                    UpdateResult result = (UpdateResult)resultObject;
286
                    if(!result.getExceptions().isEmpty()){
287
                        MessagingUtils.warningDialog(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_TITLE, this,
288
                                String.format(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_MESSAGE, result.getExceptions()
289
                                        .stream().map(ex->ex.toString())
290
                                        .collect(Collectors.joining("\n"))));
291
                    }
292
                    DescriptiveDataSet dataSet = (DescriptiveDataSet) result.getCdmEntity();
293
                    dataSet = matrix.getCdmEntitiySession().load(dataSet, true);
294
                    // update local dataset
295
                    matrix.setDescriptiveDataSet(dataSet);
296
                    matrix.loadDescriptions(descriptiveDataSetUuid, false);
297
                }
298
            } catch (InterruptedException e) {
299
                return;
300
            }
301
            monitor.done();
302
        });
303
        job.addJobChangeListener(new JobChangeAdapter(){
304
            @Override
305
            public void done(IJobChangeEvent event) {
306
                CharacterMatrixBottomToolbar.this.getDisplay().asyncExec(()->{
307
                    matrix.redraw();
308
                });
309
            }
310
        });
311
        job.schedule();
312
    }
313

    
314
    private void generateKey(UUID datasetUuid, UUID taxonUuid) {
315

    
316
        UUID monitorUuid =  CdmApplicationState.getLongRunningTasksService().generatePolytomousKey(datasetUuid, taxonUuid);
317

    
318
        String jobLabel = "Generate polytomous key";
319
        Job job = Job.create(jobLabel, (ICoreRunnable) monitor -> {
320
            SubMonitor subMonitor = SubMonitor.convert(monitor);
321
            subMonitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
322
            IRemotingProgressMonitor remotingMonitor;
323
            try {
324
                remotingMonitor = CdmStore.getProgressMonitorClientManager()
325
                        .pollMonitor(jobLabel,
326
                                monitorUuid,
327
                                50,
328
                                null,
329
                                (List)null,
330
                                subMonitor);
331
                Object resultObject = remotingMonitor.getResult();
332
                if(resultObject instanceof Exception){
333
                    MessagingUtils.errorDialog("Key generation failed", this, "Generating the polytomous key was not successfull", TaxeditorEditorPlugin.PLUGIN_ID, (Exception)resultObject, true, true);
334
                }
335
            } catch (InterruptedException e) {
336
                return;
337
            }
338
            monitor.done();
339
        });
340
        job.schedule();
341

    
342
    }
343

    
344
}
(5-5/20)